I would like to compile code similiar to this minimal test case:
macro_rules! why {
( [ $saved:ident ] $body:block ) => {
let $saved = 3;
$body
let _a = $saved;
}
}
fn bar() {
why!([saved] {
});
}
fn main() {
}
When I try to compile it, I get the following error:
src/main.rs:10:20: 10:21 error: unresolved name `saved` [E0425]
src/main.rs:10 why!([saved] {
^
src/main.rs:10:9: 11:12 note: in this expansion of why! (defined in src/main.rs)
src/main.rs:10:20: 10:21 help: run `rustc --explain E0425` to see a detailed explanation
Other macros that introduce variables work; what's the problem here?
This is because macro_rules!
is kinda broken when it comes to macros that expand to statements.
The problem is basically that it considers each statement independently for the purposes of hygiene. In other words, the third statement literally cannot see the binding defined on the first line.
In some cases, you can work around this by wrapping the statements in a block:
macro_rules! why {
( [ $saved:ident ] $body:block ) => {
{
let $saved = 3;
$body
let _a = $saved;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With