As the reference explains in section `Transcribing` about macros by example:
When forwarding a matched fragment to another macro-by-example, matchers in the second macro will see an opaque AST of the fragment type. The second macro can't use literal tokens to match the fragments in the matcher, only a fragment specifier of the same type. The
ident
,lifetime
, andtt
fragment types are an exception, and can be matched by literal tokens.
In my understanding, any fragment specifier except whose type is one of ident
, lifetime
, and tt
can only be matched in the second macro using a fragment specifier of the same type.
But this code works (playground link):
macro_rules! foo {
($l:expr) => { bar!($l); }
}
macro_rules! bar {
($l:tt) => {}
}
foo!(3);
So I'm wondering if it works using ident
or lifetime
instead of tt
, but run this code I got an error (playground link):
/*--- snip ---*/
macro_rules! bar {
($i:ident) => {}
}
foo!(a); // Error!
To my surprise, the first code still works if I change the type of $l
from tt
to literal
:
/*--- snip ---*/
macro_rules! bar {
($l:literal) => {};
}
foo!(3);
Did I misunderstand what has been explained in the reference? if I did, how to understand it correctly? Or the reference makes a mistake?