Hello,
My question relates to the behavior described here I’ve read several other posts on this topic, and I see that the outer macro expansion implicitly wraps the variable inside a Block with a None delimiter, causing the inner macro not to match.
The reference suggests using a tt (TokenTree) will avoid this. My problem is that, (ironically) I want outer! to only match block expressions.
#[macro_export]
macro_rules! inner {
($k:expr, $v:expr) => {
println!("{} = {}", $k, $v);
};
}
#[macro_export]
macro_rules! outer {
($b: block) => {
inner!($b);
};
}
fn main() {
inner!("one", "1");
outer!({"two", "2"});
}
But, if I change outer to accept tt
, the match rules aren’t greedy enough to get the whole block.
#[macro_export]
macro_rules! outer {
($b: tt) => {
inner!($b);
};
}
There are two possible solutions I see, either of which seem like they'd work.
1.) Define the variable in the match part to say, “match if it’s a block, but treat it as a token tree by the expander” or
2.) invoke the inner macro with the contents of the block, not the block itself.
Which brings me to the defile crate. It is exactly what I’m looking for, but the fact that it has so few downloads, hasn’t been updated in 3 years and has an incorrect description (appears to be the description of mini_paste) leads me to believe it’s not heavily used. Which further leads me to speculate that such a fundamental piece of functionality might be better accomplished another way. (without writing my own proc macro, in this case)
Thanks for any ideas / info / thoughts.