I'm having trouble understanding what exactly a tt
is in Rust's macro_rules!
macros.
From this answer, I thought that
tt
will match any single token or any pair of parenthesis/brackets/braces with their content.
However, the following example does not seem to follow this rule:
macro_rules! foo {
(content: $content:tt) => {
mod foo {
$content
}
}
}
foo! (
content: {
pub fn main() {
println!("Hello");
}
}
);
I would expect that the tt
would match everything contained in the {}
after content:
and that the result of the macro invocation would be
mod foo {
pub fn main() {
println!("Hello");
}
}
Instead, I get the following error message:
error: expected item, found `{`
--> src/main.rs:10:12
|
10 | content: {
| ^ expected item
What's going wrong here? Also, why does Rust tell me it's expecting an item
when I've told it to expect a tt
?
tt
is working as expected here. Your macro invocation is as follows:
foo! (
content: {
pub fn main() {
println!("Hello");
}
}
);
$content
is this:
{
pub fn main() {
println!("Hello");
}
}
So, the result is this:
mod foo {
{ // <-- Error occurs here
pub fn main() {
println!("Hello");
}
}
}
You cannot have another set of curly braces directly inside of a mod
declaration.
The solution to make your code work is to just put $content
directly after mod foo
, but I presume you already saw that:
macro_rules! foo {
(content: $content:tt) => {
mod foo $content
}
}
foo! (
content: {
pub fn main() {
println!("Hello");
}
}
);