Use local bindings at call site in Rust "macro_rules" macros

704 views Asked by At

Consider the following snippet:

macro_rules! quick_hello {
    ($to_print:expr) => {
        {
            let h = "hello";

            println!("{}", $to_print)
        }
    }
}

fn main() {
    quick_hello!(h);
}

If I compile it, I get:

error[E0425]: cannot find value `h` in this scope
  --> src/main.rs:12:18
   |
12 |     quick_hello!(h);
   |                  ^ not found in this scope

But shouldn't the quick_hello call in main expand to a block containing the let h = "hello" statement, thus allowing me to use it as a quickhand for "hello" at call site?

I might get that this is done to keep macros hygienic, but what if I require the above mentioned behaviour? Is there a way to "turn off" hygiene to achieve this?

2

There are 2 answers

2
Satsu On BEST ANSWER

As people above have noted, it is not clear what you want this macro to do. However, this compiles and prints hello:

macro_rules! quick_hello {
    (h) => {
    let h = "hello";
      println!("{}", h)  
    };
    ($to_print:expr) => {
        {
            println!("{}", $to_print)
        }
    }
}
fn main() {
    quick_hello!(h);
}
2
MaxV On

To process quick_hello call rustc is looking up for a valid expression for $to_print:expr. But h is not a valid expression at that context so rustc doesn't move forward with the macro implementation and prints the error.