Skip to content
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

Strange order dependency for macro that matches _ and ident #39964

Closed
larsluthman opened this issue Feb 19, 2017 · 2 comments · Fixed by #42913
Closed

Strange order dependency for macro that matches _ and ident #39964

larsluthman opened this issue Feb 19, 2017 · 2 comments · Fixed by #42913
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

Comments

@larsluthman
Copy link

larsluthman commented Feb 19, 2017

A macro_rules! macro with two cases that match _ and ident might not match _ depending on the order of the cases. This works:

macro_rules! foo {
    (_) => {};
    ($a:ident) => {};
}

fn main() {
    foo!(_);
}

But this doesn't:

macro_rules! foo {
    ($a:ident) => {};
    (_) => {};
}

fn main() {
    foo!(_);
}

...giving the error message:

rustc 1.17.0-nightly (306035c21 2017-02-18)
error: expected ident, found _
 --> <anon>:8:10
  |
8 |     foo!(_);
  |          ^

Why would it expect an ident there? If _ isn't an ident, shouldn't it just move on to the second macro case and match that?

@durka
Copy link
Contributor

durka commented Feb 20, 2017

Annoyingly, the macro expander doesn't attempt to handle this kind of ambiguity at all. It won't back out of $a:ident and retry the next rule, it just bails. It can only use "constants" (like _ or some other explicit token that isn't a macro variable) to disambiguate.

@Mark-Simulacrum Mark-Simulacrum added the A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) label May 23, 2017
@Mark-Simulacrum
Copy link
Member

I don't think this is really a direct issue since this basically resolves to the macro expander being unable to handle ambiguity between macro arms. As such, I'm going to close.

kennytm added a commit to kennytm/rust that referenced this issue Jul 7, 2017
bors added a commit that referenced this issue Jul 11, 2017
…seyfried

Only match a fragment specifier the if it starts with certain tokens.

When trying to match a fragment specifier, we first predict whether the current token can be matched at all. If it cannot be matched, don't bother to push the Earley item to `bb_eis`. This can fix a lot of issues which otherwise requires full backtracking (#42838).

In this PR the prediction treatment is not done for `:item`, `:stmt` and `:tt`, but it could be expanded in the future.

Fixes #24189.
Fixes #26444.
Fixes #27832.
Fixes #34030.
Fixes #35650.
Fixes #39964.
Fixes the 4th comment in #40569.
Fixes the issue blocking #40984.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants