Ross Rogers
Ross Rogers

Reputation: 24270

How can I match a literal value in a macro called from another macro?

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.

Upvotes: 3

Views: 1539

Answers (1)

ZHANG YaoNan
ZHANG YaoNan

Reputation: 31

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

Upvotes: 3

Related Questions