#Nested macro_rules! behaves differently

5 messages · Page 1 of 1 (latest)

worn crag
#

In the following example, helper_macro_bar seems to behave differently when it is called from main_macro and when it is called directly.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c1e901dd9d59c574cfd247dea8828b42

I don't understand why. As far as I can tell, both invocations of the macro get the same input. When commenting out the "invalid bar" branch of helper_macro_bar and all invalid helper_macro_bar invocations, it seems to not expect the arg1 token that comes after room: String,.

#

Interestingly, rust-analyzer's "expand macro recursively" seems to result in the expected code, but using the "expand macros" from rustc nightly triggers the weird behaviour.

worn crag
#

Here is an even more reduced version: ```rs
macro_rules! inner_macro {
( $name:ident String ) => { const $name: &str = "String found"; };
( $name:ident $ty:ty ) => { const $name: &str = "No String here"; };
}

// Causes inner_macro to always be invalid
macro_rules! wrap_macro {
( $name:ident $ty:ty ) => { inner_macro!( $name $ty ); };
}

// Works as expected
macro_rules! wrap_macro_tt {
( $name:ident $tt:tt ) => { inner_macro!( $name $tt ); };
}

wrap_macro!( EX1 String ); // No String here?
wrap_macro!( EX2 usize ); // No String here

wrap_macro_tt!( EX3 String ); // String found
wrap_macro_tt!( EX4 usize ); // No String here

inner_macro!( EX5 String ); // String found
inner_macro!( EX6 usize ); // No String here

#

It looks like types get lost at some point when matching via $ty but not when matching via $tt

#

Could this be something related to how macros are sanitized?