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 pattern ($($arg:expr)*) should be illegal #48220

Closed
semenzato opened this issue Feb 14, 2018 · 7 comments
Closed

macro pattern ($($arg:expr)*) should be illegal #48220

semenzato opened this issue Feb 14, 2018 · 7 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@semenzato
Copy link

On rustc 1.21.0 it is legal to write a rule like

($($arg:expr)*) => { println!($($arg),*) }

but the manual does not allow space as a separator in an expr list:

https://doc.rust-lang.org/book/first-edition/macros.html#syntactic-requirements

which is reasonable because it leads to ambiguities (e.g. "a b -c" could be three expressions "a", "b", and "-c", or two, "a" and "b-c"). (If you're curious, the implementation picks the second choice in this case).

@ExpHP
Copy link
Contributor

ExpHP commented Feb 14, 2018

but the manual does not allow space as a separator in an expr list

Can you show more precisely what language in the link makes you say this? I don't see anything on limitations of lists.

The argument I find much more compelling is what you mentioned in the user's thread, that the following

macro_rules! foo {
    ($a:expr $b:expr) => {};
}

is forbidden.


because it leads to ambiguities

I fear much worse; that the way such invocations are parsed may even change as the grammar of expressions is extended. This would seem to defeat the whole purpose of the follow-set rules! (but of course! They've been entirely circumvented...)

@durka
Copy link
Contributor

durka commented Feb 14, 2018

I think this may be the same as #44975.

@semenzato
Copy link
Author

In response to ExpHP: It's in the last part of the "Syntactic Requirements" section, copied below.

There are additional rules regarding the next token after a metavariable:
expr and stmt variables may only be followed by one of: => , ;

Clearly allowing ($($arg:expr)*) breaks this rule.

Durka: yes, same problem, thank you for linking this.

Sorry if I am stating the obvious, but there's no good way of allowing space-separated expressions in this context. In addition to the "-" operator, there are function calls (is f (x) one or two expressions?), vectors (a [3]) and I don't know what else (my experience with Rust is about 4 days).

@cuviper
Copy link
Member

cuviper commented Feb 15, 2018

I think calling this "space-separated" is a misnomer, because the same problem occurs without any spaces in the input at all, just depending on how the tokens are combined.

@semenzato
Copy link
Author

Thanks, agree, "space-separated" is not good. It's more like "without a separator" or more precisely "without a separating token" since whitespace can separate tokens. In any case I don't think there's any confusion here.

@gsollazzo gsollazzo added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-lang Relevant to the language team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Feb 15, 2018
bors added a commit that referenced this issue Oct 26, 2018
Disallow incorrect unseparated repetition

Macro pattern `($a:expr, $b:expr)` is invalid, for good reason.
Correctly reject pattern `($($a:expr)*)`, as it is functionally the
same.

Fix #44975, fix #48220.
bors added a commit that referenced this issue Oct 26, 2018
Disallow incorrect unseparated repetition

Macro pattern `($a:expr, $b:expr)` is invalid, for good reason.
Correctly reject pattern `($($a:expr)*)`, as it is functionally the
same.

Fix #44975, fix #48220.
bors added a commit that referenced this issue Oct 29, 2018
Disallow incorrect unseparated repetition

Macro pattern `($a:expr, $b:expr)` is invalid, for good reason.
Correctly reject pattern `($($a:expr)*)`, as it is functionally the
same.

Fix #44975, fix #48220.
bors added a commit that referenced this issue Nov 22, 2018
Warn on incorrect unseparated repetition

Macro pattern `($a:expr $b:expr)` is invalid, for good reason.
Correctly reject pattern `($($a:expr)*)`, as it is functionally the
same.

Fix #44975, fix #48220.
@steveklabnik
Copy link
Member

Triage: this text is no longer in the book; it seems like a warning was added. I'm gonna call this fixed. Please let me know if this is not the case!

@durka
Copy link
Contributor

durka commented Apr 1, 2020

Whether or not the book suggests this or not, the syntax is still allowed by rustc. The movement to fix it, or even lint on it for future deprecation (#55373, #56575) seems to have stalled.

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-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants