-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Hygiene broken in multi-statement macros #31856
Comments
I am experimentally playing with the idea of using hygiene to hide one object, then exposing another object that refers to the hidden object. The macro I have is macro_rules! take_mut {
($mut_ref:expr => $into:pat) => {
let mut scope = Scope::new();
let $into = Hole::new(&mut scope, $mut_ref);
}
} Trying to use this fails with
|
For the record, you can write code that relies on this bug. This code macro_rules! m {
($i:ident) => {
let mut $i = 2;
$i = $i + 1;
}
}
fn no_macro() {
let mut a = 1;
let mut a = 2;
a = a + 1;
println!("{}", a);
}
fn yes_macro() {
let mut a = 1;
m!(a);
println!("{}", a);
} produces code that looks the same under pretty-expansion, but |
Fix macro hygiene bug This fixes rust-lang#32922 (EDIT: and fixes rust-lang#31856), macro hygiene bugs. It is a [breaking-change]. For example, the following would break: ```rust fn main() { let x = true; macro_rules! foo { () => { let x = 0; macro_rules! bar { () => {x} } let _: bool = bar!(); //^ `bar!()` used to resolve the first `x` (a bool), //| but will now resolve to the second x (an i32). }} foo! {}; } ``` r? @nrc
Multi-statement macros (macros that expand to multiple statements) are hard to use because hygiene runs separately on each line, meaning it's very easy to "lose" identifiers.
Here are some examples. The macro is trying to declare a variable in the scope where it was called, but it takes multiple statements to construct.
This is a long-standing bug, not a regression. I previously reported this here and here (can likely be closed) but it wasn't very visible. ping @Sgeo @chris-chambers
The text was updated successfully, but these errors were encountered: