I've been trying to use Rust macros but I'm hitting a stumbling block with token trees, I'm given to understand a token tree will accept any valid sequence of tokens, grouping them into a hierarchy based on paired ()
, []
, {}
.
When I try to pass in any sequence of tokens, I get parse errors that reject the 2nd token in the sequence.
#![feature(trace_macros)]
#![allow(dead_code)]
macro_rules! repro {
($foo:tt) => {
stringify!($foo);
};
}
fn main() {
trace_macros!(true);
// println!("{}", repro!(bar)); works
//these break, but succeed for meta type expr
println!("{}", repro!(bar: fizz));
println!("{}", repro!(1 + 2));
trace_macros!(false);
}
In the above code, the ':' and '+' tokens trigger failures:
error: no rules expected the token `:`
--> src/main.rs:15:30
|
4 | macro_rules! repro {
| ------------------ when calling this macro
...
15 | println!("{}", repro!(bar: fizz));
| ^ no rules expected this token in macro call
note: trace_macro
--> src/main.rs:15:5
|
15 | println!("{}", repro!(bar: fizz));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expanding `println! { "{}" , repro ! (bar : fizz) }`
= note: to `{ $crate :: io :: _print (format_args_nl ! ("{}" , repro ! (bar : fizz))) ; }`
note: trace_macro
--> src/main.rs:15:20
|
15 | println!("{}", repro!(bar: fizz));
| ^^^^^^^^^^^^^^^^^
|
= note: expanding `repro! { bar : fizz }`
error: no rules expected the token `+`
--> src/main.rs:16:29
|
4 | macro_rules! repro {
| ------------------ when calling this macro
...
16 | println!("{}", repro!(1 + 2));
| ^ no rules expected this token in macro call
note: trace_macro
--> src/main.rs:16:20
|
16 | println!("{}", repro!(1 + 2));
| ^^^^^^^^^^^^^
|
= note: expanding `repro! { 1 + 2 }`
note: trace_macro
--> src/main.rs:16:5
|
16 | println!("{}", repro!(1 + 2));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expanding `println! { "{}" , repro ! (1 + 2) }`
= note: to `{ $crate :: io :: _print (format_args_nl ! ("{}" , repro ! (1 + 2))) ; }`
I would expect that bar: fizz
maps to ['bar', ':', 'fizz']
and 1 + 2
maps to ['1', '+', '2']