-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Macro rules backtracking #33840
Conversation
r? @sfackler (rust_highfive has picked a reviewer for you, use r? to override) |
r? @nrc |
07a1b18
to
dde0e88
Compare
Potential |
No. The parsing algorithm is the same. There is actually no « backtracking » as you may understand it. The parsing algorithm works on a single arm and, on failure, will try the next arms with the same tokens. This PR only make sure all errors encountered during the parsing for an arm are not fatal but properly reported. There's no change in complexity here. In fact, the parsing algorithm could already be called on every arm if no non-terminal parsing errors occured. |
dde0e88
to
ce31cb7
Compare
… of increasing it.
This allows to cancel an error with only an immutable access to the `Handler`. Mutable access is already not required to emit an error anyway.
b9eb282
to
0d8dae4
Compare
match name { | ||
"tt" => { | ||
p.quote_depth += 1; //but in theory, non-quoted tts might be useful | ||
let res: ::parse::PResult<'a, _> = p.parse_token_tree(); | ||
let res = token::NtTT(P(panictry!(res))); | ||
let res = token::NtTT(P(try!(res))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: prefer ?
to try!
0d8dae4
to
be53b20
Compare
67c1790
to
13a8c8d
Compare
lgtm with a cursory read over the code, but r? @pnkfelix for a detailed review |
let nt = match parse_nt(&mut rust_parser, span, | ||
&ident.name.as_str()) { | ||
Ok(nt) => Rc::new(MatchedNonterminal(nt)), | ||
Err(diag) => return Failure(diag) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to myself: we must not fail here, but rather just remove the current parsing item from the stack.
Note for myself and for others: Allright we have a problem here. As I noted in the comment above, we currently only backtrack from an arm, not from a parsing item. That means that if you have a macro like this: macro_rules! foo(
( $( $e:expr ),* some_other_tokens ) => ...
) If we provide it input that doesn't match This sounds easy to fix: just remove the current parsing item from the stack. macro_rules! foo(
( $( $e:expr , )* $( $i:ident : $t:ty , )* ) => ...
) Before type ascription syntax, This was not a problem before because failure to match a NT (such as This problem is in fact the very same as the one with multiple-arm macros: macro_rules! foo(
$( $e:expr ) => ... ;
$( $i:ident : $t:ty ) => ...
) So I believe that my analysis for multiple-arm macros could be applied to fix the issue with the current future-proofing analysis for single-arm macros. But until we sorted that out, we have two solutions for this PR:
(By fixing this issue, I mean: making sure the parser backtracks out of a sequence repetition.) |
13a8c8d
to
24b9e39
Compare
@LeoTestard as we said in person, this is indeed a drag, though I guess it just ups the priority of investigating the other future-proofing problem. :( |
☔ The latest upstream changes (presumably #34424) made this pull request unmergeable. Please resolve the merge conflicts. |
ping, @LeoTestard looks like this needs a rebase? |
@alexcrichton Yes indeed, but it's blocked anyway until we have a fix for the future-proofing issue. I don't know what we should do with this PR. Maybe we can just close it and reopen it later? |
Ah either way is fine by me, this is now active in the last 5 hours rather than 21 days, so I'm happy at least :) |
This is quite stalled. @pnkfelix @LeoTestard is there any chance of this PR landing? Should we close? |
@brson Yes, there is still a chance. I thought again about this problem after I found the problem I mentioned above, and I no longer think it's a problem. It turns out that I did not understood how the parser handled ambiguity at the time. I should be able to sum up the situation in more detail. |
Any chance of this happening? I am tempted to just close this PR until you or someone else is ready to move forward here; this is going to be extremely out of date, right? |
Seems reasonable to close the PR in the meantime, though @LeoTestard I'd like to hear more about what you have in mind. |
@steveklabnik The code is probably quite out of date indeed, I agree that the PR can be closed in the meantime. @nikomatsakis Sure. I promise I'll take the time to write about it at some point, but I'm quite busy these days. |
This fixes
macro_rules!
to implement the wanted backtracking semantics: if an arm fails to match, the next arm is tried, and so on.This was previously not the case because of hard errors emitted during parsing of non-terminals. Now that the parser code has been fixed not to panic but to return a
DiagnosticBuilder
in case of error, it's easy to catch those errors and signal that the arm failed to match.This PR probably contains a bit of hackery, so it's flagged as WIP so that people can review it.