Ident format specifier matching keywords?


#1

It’s suprising for me to find that ident in macros has ambiguity with keywords:

macro_rules! idents_followed_by_keyword {
    ($($slot:ident,)+ else) => ($(let $slot = 0;)+);
}

fn main() {
    idents_followed_by_keyword!(_a, else);
}

This fails compilation with:

error: local ambiguity: multiple parsing options: built-in NTs ident ('slot') or 1 other options.

As keywords cannot be used in place of identifiers, would it make sense to fix the matcher? This would allow more useful repeating syntaxes in macros, without a need to put parentheses or other cludges around places where identifiers are expected.


#2

The input to a macro is lexical (tokens) and keywords are not part of Rust’s lexical syntax. This is for simplicity and consistency: syntax extensions don’t need to handle keywords (which may not be special in their own syntax) differently. I think you might be right that matchers ought to be Rust-keyword-sensitive. I’ll think about it, it would be complex to implement.

sent from my phone


#3

Thank you. I have filed this as a wishlist issue: https://github.com/rust-lang/rfcs/issues/772


#4

I’d prefer the matcher system to be more cleverer. I mean, if you’re got a repeat followed by something, it should be smart enough to say “well, both match, but then I’d never be able to terminate, so I’ll stop repeating”.

Heck, just a nicer way of stopping repetitions. I have to admit I went the lazy route with the scan*! macros, and just added negative lookahead assertions to the syntax. A little ugly, but works just fine.