Search code examples
rustmacroshygienerust-decl-macros

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


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?


Solution

  • 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);
    }