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
Having a variable in scope affects macro invocation parsing #9737
Comments
This is a consequence of hygiene: the macro is looking for the identifier This is similar to how keyword arguments behave in Racket:
...but not as sophisticated, as Racket allows you to define a Of course, "but Racket does it that way" isn't an automatic justification for everything macro-related. Maybe the Rust macro parser would make more sense if we were treating |
Implementing the behavior that the OP expects would be fairly simple: it'd just mean having the macro parser compare identifiers unhygienically instead of hygienically. |
Yes, that seems right to me. I think we should perform that comparison unhygienically. I have a nagging feeling that this could cause unwanted behavior in sufficiently "interesting" situations--I'm thinking specifically of macros that expand into macro definitions. Well, this may be a non-issue; currently, even if we fix macros-that-define-macros, there's no way to use a pattern variable in another pattern--it would just be a new binding. To wit: macro_rules!(($i:ident)=>(macro_rules!(($i : 3)=>(3)))) Anyhow, WRT the bug report: I agree. We should compare these by name, not as identifiers. Is that a one-liner? ... sigh... |
Added a test case for this in my code, haven't made pull request yet. |
Visiting for triage. @jbclements did that ever get submitted/land? |
No, I don't believe so. This still looks like a simple change. |
if this gets fixed by 1.0, great. But it doesn't block the release also, if there is a fix that can be shown to not break any existing code, then this would be classified as "just as bug" and thus such a fix could be landed post 1.0. P-high, not 1.0. |
I believe this is fixed as the following runs without errors on playpen stable: macro_rules! f((v: $x:expr) => ( println!("{:?}", $x) ));
fn main() {
let v = 5;
f!(v: 3);
} |
(Edit: I am also inclined to close this ticket) The most obvious variation I could think of that might still exhibit the problem, namely one where the macro is defined within the same scope that binds That is, compiles and runs: #![allow(unused_variables)]
macro_rules! f((v: $x:expr) => ( println!("{:?}", $x) ));
fn foo() {
macro_rules! g((v: $x:expr) => ( println!("{:?}", $x) ));
f!(v: 3);
g!(v: 3);
}
fn bar() {
let v = 4;
macro_rules! g((v: $x:expr) => ( println!("{:?} {:?}", $x, v) ));
let v = 5;
f!(v: 3);
g!(v: 3);
}
fn main() {
foo();
bar();
} |
Agreed. |
Closing as per previous comments. |
This is really weird. If I have a macro that expects a particular alphabetic token, and I define a variable with that same token, the macro suddenly stops parsing.
Macro in question:
I can invoke it like
and it will work just fine. But the following blows up:
The text was updated successfully, but these errors were encountered: