Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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.
# for free to join this conversation on GitHub. Already have an account? # 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