You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Macro rules: using lifetime specifier inside recursion causes local ambiguity #50903
I'm on a train right now with limited connectivity, so I cant push my PR, but I have a change that I've compiled and tested, and I'm not sure if it's working correctly, I could use some more background.
I added this to may_begin_with, compiled and set as a custom toolchain all good so far
I created a new cargo bin project (I didn't see any tests for macro_parser or any test dirs in the libsyntax directory, not sure if there's a better way to do this) and made the main function define that macro and use it, as in the original example. With nightly it showed the expected ambiguity error. Then I used rustup overrides with my custom toolchain and rebuilt, and it compiled with no errors. Is this the expected behavior when parsing the macro? I'm unclear on how the macro parser works in rust. Is it that, before adding this branch, when parsing 'a, # they both matched the :lifetime specifier. But after adding the bit that says "no that ain't a lifetime," it no longer gets caught by that arm of the macro, and when parsing the #, it just skips it and doesn't complain? I guess I was expecting it to say something like "lifetimes cant start with #" instead of the local ambiguity, not for it to just stop being an error.
Also, you mentioned reviewing the rest of the function to see if other things didn't consider lifetime or other new syntax additions, but I'm not sure what other syntax additions there are to consider.
Then I used rustup overrides with my custom toolchain and rebuilt, and it compiled with no errors. Is this the expected behavior when parsing the macro?
Yes this is the expected behavior. When may_begin_with returns false, the parser knows that # is definitely not a :lifetime and thus stop matching against $($lif2:lifetime,)*. The original template expects a # next, which it matched, and thus everything goes fine.
Also, you mentioned reviewing the rest of the function to see if other things didn't consider lifetime or other new syntax additions, but I'm not sure what other syntax additions there are to consider.
Basically to check the interaction with all other fragment specifiers, e.g.
Interpolated lifetimes are encoded as NtLifetime which I don't see listed in the may_begin_with function. But maybe adding a "lifetime" case is sufficient to disambiguate the above examples.
(For new syntax I'd like to reserve DotDotEq alongside DotDotDot in :pat, though that would be off-topic and could also be a breaking change.)
Activity
kennytm commentedon May 19, 2018
The problem is that currently a lifetime "may start with anything" because we haven't spelled out the rules.
Mentoring instruction
Edit
macro_parser.rs, and insert the case"lifetime"into themay_begin_with()function.rust/src/libsyntax/ext/tt/macro_parser.rs
Lines 725 to 739 in 5c3960c
You may also want to review this function to see if any case did not consider
NtLifetimeand recent syntax additions.yaahc commentedon May 21, 2018
I'd like to take this issue
yaahc commentedon May 25, 2018
I'm on a train right now with limited connectivity, so I cant push my PR, but I have a change that I've compiled and tested, and I'm not sure if it's working correctly, I could use some more background.
I added this to may_begin_with, compiled and set as a custom toolchain all good so far
I created a new cargo bin project (I didn't see any tests for macro_parser or any test dirs in the libsyntax directory, not sure if there's a better way to do this) and made the main function define that macro and use it, as in the original example. With nightly it showed the expected ambiguity error. Then I used rustup overrides with my custom toolchain and rebuilt, and it compiled with no errors. Is this the expected behavior when parsing the macro? I'm unclear on how the macro parser works in rust. Is it that, before adding this branch, when parsing
'a, #they both matched the:lifetimespecifier. But after adding the bit that says "no that ain't a lifetime," it no longer gets caught by that arm of the macro, and when parsing the#, it just skips it and doesn't complain? I guess I was expecting it to say something like "lifetimes cant start with #" instead of the local ambiguity, not for it to just stop being an error.Also, you mentioned reviewing the rest of the function to see if other things didn't consider lifetime or other new syntax additions, but I'm not sure what other syntax additions there are to consider.
kennytm commentedon May 25, 2018
@jrlusby
Yes this is the expected behavior. When
may_begin_withreturns false, the parser knows that#is definitely not a:lifetimeand thus stop matching against$($lif2:lifetime,)*. The original template expects a#next, which it matched, and thus everything goes fine.This is similar to the behavior of
Basically to check the interaction with all other fragment specifiers, e.g.
Interpolated lifetimes are encoded as
NtLifetimewhich I don't see listed in themay_begin_withfunction. But maybe adding a"lifetime"case is sufficient to disambiguate the above examples.(For new syntax I'd like to reserve
DotDotEqalongsideDotDotDotin:pat, though that would be off-topic and could also be a breaking change.)yaahc commentedon May 25, 2018
apparently not
Auto merge of #51480 - dtolnay:lifetime, r=kennytm