2

How can I pass true or false through a macro and into another macro, where the inner macro matches on true or false? Not expr, but literally true or false.

When I do the following, I can't find the correct syntax to match against the boolean token:

#[macro_export]
macro_rules! true_false {
    (true) => { // < ------------- I really want the match to be at this level
        println!("true!");
    };
    (false) => {// < ------------- or here
        println!("false!");
    };
}

#[macro_export]
macro_rules! intermediary {
    ($boolean:literal) => { // < -- Is there token type I can set here?
        crate::true_false!($boolean);
    }
}

fn main() {
    crate::intermediary!(true);
    crate::intermediary!(false);
}

I realize that I can use match inside the inner macro and that the "constant propagation" compiler optimization will nuke the branch I don't care about. However, I want the inner branch to have the same block scope as the block the intermediary macro is being called at.

This may be x-y problem space, but despite my actual problem, I'm wondering if there is syntax to solve the problem I presented above.

Ross Rogers
  • 23,523
  • 27
  • 108
  • 164
  • 2
    You might be able to fix it if you pretend you are not trying to match a literal and are instead matching a token instead (`$boolean:tt`). Also there is a typo in this example where `$boolen` is misspelled which would likely cause it to fail. – Locke Feb 10 '22 at 18:36
  • 2
    @Locke, That was it! Post an answer for unbelievably valuable street cred and fake internet points. – Ross Rogers Feb 10 '22 at 18:40

1 Answers1

2

I have met the same problem. After trying for almost half a day, I found changing literal to tt works. It will pass true as a token instead of a literal value, so you can match it in the next macro.

macro_rules! intermediary {
    ($boolean:tt) => { // < -- Is there token type I can set here?
        crate::true_false!($boolean);
    }
}

https://doc.rust-lang.org/reference/macros.html#macro-invocation