Could macros support optional trailing tokens following a TokenTree repetition?

In effect, I'd like to be able to write a macro something like this:

example! {
  "hello",
  Apple = "banana",
  Cherry = "danish",
  Eclaire,
}

In other words, a mixture of "expr" forms or "name = expr" forms. A macro like this can be implemented using an Incremental TT Muncher; for example:

macro_rules! example {

    ($name:ident = $value:expr, $($tts:tt)*) => {
        example!($($tts)*)
    };

    ($value:expr, $($tts:tt)*) => {
        example!($($tts)*)
    };

    () => {}

}

However, if I understand correctly, a macro of this form can't allow for any trailing tokens following the TokenTree repetition, so "natural" code forms like this aren't possible with this implementation:

example!("a", b = 1)

In theory, we might try matching an optional comma following a TokenTree repetition, but that fails:

error: local ambiguity when calling macro example: multiple parsing options: built-in NTs tt ('tts') or 1 other option

And this also implies that other approaches that might try to adjust where the comma is consumed in the macro are effectively doomed to fail.

Is there a way forward that I'm missing, or some reasonable extension that could be proposed which the Rust team might consider including?

For what it's worth, I could imagine something like "lazy" repetitions using *?, where something like:

($($tts:tt)*? $(,)?) => { ... }

would allow a final (optional) comma to be matched separately from the TokenTree repetition, but I'm not sure how much extra complexity this would introduce into the macro engine. (Maybe it's okay as long as we allow only a single repetition of this form?)

You can just make the trailing parts optional:

macro_rules! example {

    ($name:ident = $value:expr $(, $($tts:tt)*)?) => {
        $(example!($($tts)*))?
    };

    ($value:expr $(, $($tts:tt)*)?) => {
        $(example!($($tts)*))?
    };

    () => {}

}

By the way, these sorts of questions are better suited to https://users.rust-lang.org.

1 Like

Thanks! I didn't realize a nested repetition like that in this position would work. I appreciate the help and I'll make sure to ask such questions on the appropriate forum next time.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.