Also, regarding the initial question, once a macro input is captured in a metavariable whose kind is not
:ident, then it gets "wrapped in invisible parenthesis" which prevents it from matching any other literal rule.
foo!( bool ) receives the sequence of tokens
`bool`, which can be parsed as a
:ty and captured within one, as
$tp := `⦑bool⦒`, (I am using
⦒ to represent the "invisible parenthesis"), which is then fed to an invocation of
foo!(_ $tp), i.e.,
foo!( _ ⦑bool⦒ ), which receives the sequence of tokens
`_`, `⦑bool⦒`, which does not match the rule expecting
`_`, `bool`,, (nor the one with
i32), and only matches the one with no hardcoded syntax: the nested
_ $tp:ty capture (I don't know if it then gets yet another layer of invisible parens or if Rust is smart enough to know those are not needed anymore).
You can use the
::defile crate, which explains this phenomenon, to "remove these invisible parenthesis", but in general, the
$(_:tt)* pattern with a muncher is the usual