Switch on inner macro rules based on input literal

I’m trying to create a macro which, given a list of expressions, will use each of them, with literal zero being treated one way (in fact, it should be expanded to noop) and all other expressions the other. Here’s the simplified example:

macro_rules! test {
    ($($x:expr),+) => {$(
        test!(@impl $x);
    )+};
    (@impl 0) => {};
    (@impl $x:expr) => {
        println!("{:?}", $x);
    }
}

fn main() {
    test!(@impl 0);
    test!(0, (1, 2, 3));
}

Playground

However, in this case the second test! invocation prints all both the number and the tuple, ignoring the second arm and going only for the third one. Am I doing it wrong? I can’t use runtime check, since the types ate different.

I tried to remove the third branch but it still didn’t want to go with the right branch. I think the parser see expr in input and won’t change from here. So the solution I found is to change expr in the first branch to tt, this way the compiler can’t make assumption and does the right thing. I don’t think you can abuse the tt since it will hit a wall in the first branch but I might be wrong.

EDIT: in the second branch, 0 might be seen as a literal maybe?

1 Like

Worked, thanks!