Declarative macro metavariable repetition levels

Hi,

since when does this code work?

macro_rules! distribute {
    { $($fun:ident($($arg:ident)*))* } => {
        stringify!($($($fun $arg),*);*)
    }
}

fn main() {
    println!("{}", distribute!{ f(a b c) g(d e) });
}

Originally I thought it wouldn't work because the $fun metavariable is defined in one level of repetition ($(_)*) but expanded in two ($($(_)*)*), but to my surprise it works well.

Even the reference says:

A metavariable must appear in exactly the same number, kind, and nesting order of repetitions in the transcriber as it did in the matcher

So I guess this is a (relatively) recent change and the reference is not yet up to date. Is that correct? When did the change happen?

(Not complaining about this one, but I wonder what other possibilities am I missing)

Compiles since 1.0.0, so I think it's just incorrect or misleading documentation.

1 Like

I feel like $func is treated as a constant within the inner repetition. It's not like you're forbidden from using non-repeating variables inside a repeating section.

it always works like this, as @quinedot said, it's probably just bad documentation.

more interestingly, this also works (as long as the two groups of repetitions have same length):

macro_rules! zip {
    ($($a:expr),* ; $($b:expr),*) => {
        stringify!($(($a, $b)),*)
    }
}

fn main() {
    println!("{}", zip!(1, 2, 3; a, b, c));
}
1 Like