I\'m trying to achieve something like this (simplified):
macro_rules! atest {
($closure:tt) => {
let x = 5;
println!(\"Result is {}\",
Peter's answer explains why what you're doing won't work. This is part of what's referred to as "macro hygiene": things declared inside macros can't "leak" into the surrounding scope.
A common workaround for the problem you're facing is to pass the name of the identifier into the macro as another argument:
macro_rules! atest {
($x:ident, $closure:tt) => {
let $x = 5;
println!("Result is {}", $closure())
};
}
fn main() {
atest!(x, (|| 5 + x));
}
This will work because naming x puts it in the caller's scope, even though the declaration is inside the macro.
You might notice that the closure is kind of unnecessary, at least in this example -- you could just pass 5 + x as an expression to the macro and have it expanded inline.
macro_rules! atest {
($x:ident, $value:expr) => {
let $x = 5;
println!("Result is {}", $value)
};
}
You call this macro like atest!(x, 5 + x), which looks a little bit like a closure of its own. That might give you the idea of writing atest!(|x| 5 + x) instead. And that will also work, with a variable scoped to the closure:
macro_rules! atest {
($closure:expr) => {
let x = 5;
println!("Result is {}", $closure(x))
};
}