Given this macro:
macro_rules! mac {
([$p:path] $body:tt) => {
($p $body)
};
}
fn main() {
mac!([foo::bar] { foo: "bar" });
}
For some reason it expands into this:
fn main() { (foo::bar, { (/*ERROR*/) }); }
What I expected:
fn main() { (foo::bar { foo: "bar" }); }
I have no idea why rust adds a comma there when there isn't a single one in my program. Is it assuming I'm trying to create a tuple because of the parenthesis and automatically inserting the comma for me? I find it strange that something as abstract as macros would do that.
If we change the parenthesis to brackets like so:
macro_rules! mac {
([$p:path] $body:tt) => {
[$p $body]
};
}
I get this error instead:
error: expected one of `,`, `.`, `;`, `?`, `]`, or an operator, found `{`
--> src/main.rs:8:21
|
8 | mac!([foo::bar] { foo: "bar" });
| ^ expected one of `,`, `.`, `;`, `?`, `]`, or an operator
What I expected:
fn main() { [foo::bar { foo: "bar" }]; }
The error isn't very clear but I'm guessing its somewhat related to the previous compile issue.
Finally, if we remove delimiters altogether:
macro_rules! mac {
([$p:path] $body:tt) => {
$p $body
};
}
I get the expected result:
fn main() { foo::bar { foo: "bar" }; }
I can think of a few ways to get around this with tt-munching but I don't quite understand why these macros error in the first place. Is this behavior a bug or intentional design?