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

Macro parsing ambiguity rules overly strict about repetition of the same token #24827

Closed
joshtriplett opened this issue Apr 25, 2015 · 10 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@joshtriplett
Copy link
Member

RFC 550 (https://github.com/rust-lang/rfcs/blob/master/text/0550-macro-future-proofing.md) restricted macro syntax to future-proof against changes to Rust syntax. However, this breaks a case that can be handled unambiguously, namely repetition of the same token that splits off the rightmost rather than leftmost item:

macro_rules! foo {
    () => ( ... );
    ( $($init:ident)* $last:ident ) => ( ... foo! { $($init)* } );
}

This produces the following error:
error: local ambiguity: multiple parsing options: built-in NTs ident ('init') or ident ('last') or 0 other options.

This kind of syntax is useful for recursively parsing a list and repeatedly dropping the last item (rather than repeatedly dropping the first).

Rust should be able to handle this case unambiguously, as long as the repeated token type can't match the closing delimiter of the macro, which ident clearly never will.

@joshtriplett joshtriplett changed the title Macro parsing ambiguity rules overly strict about repitition of the same token Macro parsing ambiguity rules overly strict about repetition of the same token Apr 25, 2015
@joshtriplett
Copy link
Member Author

Note that this applies even if the macro requires a delimiter between the tokens:

macro_rules! foo {
    () => ( ... );
    ( $($init:ident,)* $last:ident ) => ( ... foo! { $($init),* } );
}

@steveklabnik steveklabnik added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) labels Apr 28, 2015
@nikomatsakis
Copy link
Contributor

cc @pnkfelix

But that said, I don't really think this has much to do with RFC 550. I think this is a problem with the macro parser's greedy parsing strategy (combined with its inability to ever fallback).

@pnkfelix
Copy link
Member

Yes local ambiguity messages arise during expansion, not the ahead of time future proofing check

@tinco
Copy link
Contributor

tinco commented Jun 19, 2016

I've got exactly this same problem, trying to extract the last element from a list doesn't work because of this issue.

@pnkfelix
Copy link
Member

cc @LeoTestard

@Mark-Simulacrum
Copy link
Member

This compiles successfully today. Marking as E-needstest.

@Mark-Simulacrum Mark-Simulacrum added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label May 6, 2017
@fflorent
Copy link

fflorent commented May 12, 2017

@Mark-Simulacrum I encounter the same issue. AFAICT, it doesn't compile (or I may miss something) :
https://is.gd/rj5hNJ

Florent

@Mark-Simulacrum
Copy link
Member

Hm, yeah, you're right. Not sure what I tested. Unmarking E-needstest.

@Mark-Simulacrum Mark-Simulacrum removed the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label May 12, 2017
@kennytm
Copy link
Member

kennytm commented Jun 26, 2017

Same as #42838? You certainly need to back-track one token from init in order to match the last.

@Mark-Simulacrum
Copy link
Member

Yeah, this is unlikely to get solved differently from #42838 so closing in favor of that.

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, ..) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

8 participants