How to know what expansion a macro pattern should use

#1

The github-rs crate has the following macro defined:

macro_rules! impl_macro {
    (
        $(@$i: ident
            $(|=> $id1: ident -> $t1: ident)*
              |
            $(|=> $id2: ident -> $t2: ident = $e2: ident)*
            $(|?> $id3: ident -> $t3: ident = $e3: ident)*
        )+
    )=> {
        $(
            $(
                // How does one know what repetition goes here?
            )*
            $(
                // How does one know what repetition goes here?
            )*
            $(
                // How does one know what repetition goes here?
            )*
            }
        )+
    };
}

In it there are 1 pattern with 3 nested pattern. What I dont understand is how to select what of the 3 patterns should go into each expansion. So far I have concluded that the order of the expansions does not have to match the order of the patterns.
My last guess is that Rust is smart enough to match a pattern to an expansion given the captures used, is this the case?

0 Likes

#2

Yes the compiler will expand based on what you use.
For example:

$(
    $(
        $id1
    )*
    $(
        $id2
    )*
    $(
        $id3
    )*
)+

But even crazier, if your patterns have the same number of iterations and are at the same depth, you can use them in the same expansion.

3 Likes