Why is an invalid literal not handled by another arm in a macro?

I want to write a macro to instantiate a big integer in a clean manner, and the first step is to read the integer literal correctly. The first version I have is

macro_rules! bigint {
    ($tt:tt) => {
        println!("caught {}", ::core::stringify!($tt)); // for debug
        // some logic to create a big integer from the string
    };
}

and this macro can nicely handle very long literals like bigint!(100000000000000000000000000000000000000000000000000000000000000000000000).

One drawback of this approach is that it has to invocate the string parser even if the integer is small enough to fit in a native integer type (i.e. u128), so then what I tried next is

macro_rules! bigint {
    ($val:literal) => {
        println!("caught literal {}", $val);
        let val: u128 = $val;
        // some logic to create a big integer from val
    };
    ($tt:tt) => {
        println!("caught {}", ::core::stringify!($tt));
        // some logic to create a big integer from the string
    };
}

but this time bigint!(100000000000000000000000000000000000000000000000000000000000000000000000) will cause an compilation error: error: integer literal is too large. I'm wondering if the first matching arm failed, why wouldn't the second arm be tried?

Because the literal did match the first clause. By the time the "integer literal is too big" error is emitted, macro expansion is likely over – that error is not of a syntactic nature, it requires actually evaluating the literal.

Yes the first arm did match, but I thought that the compiler will try other arms if compilation error happened in one of the arm..

In this specific case, is there any workaround for this?

The other arms are retried if they don't match. This is exactly what I'm talking about – it's not possible to detect a const evaluation error at macro expansion time, because macro expansion is over at that point.

Write a const function instead.

1 Like

Thanks for the help, I guess I would follow your suggestion.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.