::defile
Helper proc-macro to "ungroup" a captured metavariable (thus potentially breaking their hygiene, hence the name).
This is useful when using helper macro_rules macros, that need to parse using some special rule (e.g. :expr, :path, :pat), but that later want to further inspect the captured variable.
This is not something a macro_rules! can do on its own, since such so-called metavariables are seen as an opaque single token (:tt) (the sequence of tokens captured in the metavariable have been grouped (≈ parenthesized) but using invisible parenthesis.
Example
check_all_exprs!;
outputs:
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`42`,
]
^^^^^^^^^^^^^
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`1 + 1`,
]
^^^^^^^^^^^^^
-
That is:
-
The token
42does not match42! -
That being said, the expression
1 + 1is viewed as a single indivisible token too.Indeed, that's kind of the point of this behavior: if we do
2 * $exprwhere$exprcaptures1 + 1we expect the result to be2 * (1 + 1)instead of2 * 1 + 1!
-
But by doing:
we do get:
vvvvvvvvvvvvv
Got `42`!
^^^^^^^^^^^^^
vvvvvvvvvvvvv
Did not get `42`. Instead, got the following tokens:
[
`1`,
`+`,
`1`,
]
^^^^^^^^^^^^^
42has matched the literal 42, but be aware that this has also resulted in1 + 1getting split. So, if you were todefileexpressions such as2 * @$expr, you may not obtain the expected result! Use with caution.
Caveats
Currently (1.45.0), there are several bugs regarding the interaction between
macro_rules! macros and procedural macros, that may lead to defile! and any
other helper procedural macro to split groups that are not @-prefixed.
Hopefully those bugs are solved, making the actual implementation of defile!
meaningful.