-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fix macro hygiene regression #34374
Fix macro hygiene regression #34374
Conversation
02e7d44
to
b65bc42
Compare
b65bc42
to
9a6864d
Compare
This is the simplest way I could come up with to fix the regression while keeping #32922, #31856, #10681, and #26223 fixed. While I am very confident that it is correct, we (understandably) might not want to backport this big of a change to beta. In that case, I think we should consider reverting #32923 on beta to avoid regressing hygiene on stable. However, the hygiene bug that #32923 fixes, i.e.: fn main() {
let x = 0;
macro_rules! foo { () => {
let x = 1;
println!("{}", x); // prints `0` on stable, should print `1`
} }
m!();
} is arguably worse than the regression. |
What is the motivation for removing all the unit tests? r+ other than that. |
@nrc I believe it would be a better use of time to write more That being said, I can try to rewrite the unit tests if you think it's worth it. |
Also, I'm working on dramatically simplifying the hygiene algorithm (without changing semantics) to make it feasible to expand macros in an arbitrary order (needed for macro modularization). I discovered this regression while testing my implementation. Most of the unit tests are not relevant to the simplified implementation. EDIT: Finished the hygiene simplification, see PR #34570. |
I added some more hygiene tests. r? @nrc |
@bors: r+ |
📌 Commit eef8485 has been approved by |
Fix macro hygiene regression The regression was caused by #32923, which is currently in beta. The following is an example of regressed code: ```rust fn main() { let x = 0; macro_rules! foo { () => { println!("{}", x); // prints `0` on stable and after this PR, prints `1` on beta and nightly } } let x = 1; foo!(); } ``` For code to regress, the following is necessary (but not sufficient): - There must be a local variable before a macro in a block, and the macro must use the variable. - There must be a second local variable with the same name after the macro. - The macro must be invoked in a statement position after the second local variable. For example, if the `let x = 0;` from the breaking example were commented out, it would (correctly) not compile on beta/nightly. If the semicolon were removed from `foo!();`, it would (correctly) print `0` on beta and nightly. r? @nrc
cc @rust-lang/compiler Thoughts on backporting? We hope to produce a new beta soon and would love to include this. |
somewhat ambiguous about backporting. I think the patch is right, but it is pretty big for a backport, so I'd want to see it properly motivated, i.e., the regression is causing trouble, it's not just a technicality. If that is the case, then happy to backport. |
@jseyfried do you know if this was causing trouble in the wild? |
Note that we plan on building the stable 1.10 release tomorrow, so this is unlikely at this point to make a backport. If it's critical to include, though, we can push schedules back and make it work! |
@alexcrichton No, as far as we know this has no impact in the wild, definitely not critical to include. I still think it would be better to include it, but it's not a big deal -- not worth pushing back the release. |
Ok, thanks for the update @jseyfried! In that case I'm going to remove the beta-nominated tag from this, but again if anything comes up we can make it work. |
The regression was caused by #32923, which is currently in beta.
The following is an example of regressed code:
For code to regress, the following is necessary (but not sufficient):
For example, if the
let x = 0;
from the breaking example were commented out, it would (correctly) not compile on beta/nightly. If the semicolon were removed fromfoo!();
, it would (correctly) print0
on beta and nightly.r? @nrc