-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
It doesn't seem possible to generate unit struct declaration from a macros in neither stable nor nightly version of Rust.
A simplified playground sample:
macro_rules! def_struct {
($name:ident $($body:tt)*) => {
pub struct $name $($body)*
};
}
def_struct!(X {}); // compiles
def_struct!(Y); // doesn't
fn main() {}
When trying to expand the second macro call, Rust complains:
error: expected `where`, `{`, `(`, or `;` after struct name, found `<eof>`
--> src/main.rs:3:16
|
3 | pub struct $name $($body)*
| ^^^^^
...
8 | def_struct!(Y); // doesn't
| --------------- in this macro invocation
If I add a semicolon as it asks right after the struct definition, the unit macro call starts compiling fine:
macro_rules! def_struct {
($name:ident $($body:tt)*) => {
pub struct $name $($body)*;
};
}
def_struct!(Y); // compiles
def_struct!(X {}); // doesn't
fn main() {}
but the other one fails instead:
error: macro expansion ignores token `;` and any following
--> src/main.rs:3:31
|
3 | pub struct $name $($body)*;
| ^
|
note: caused by the macro expansion here; the usage of `def_struct!` is likely invalid in item context
--> src/main.rs:8:1
|
8 | def_struct!(X {}); // compiles
| ^^^^^^^^^^^^^^^^^^
The two errors seem to contradict each other here. The only obvious workaround to make both cases work I could find is to split macro definition into two, one with semicolon and another without:
macro_rules! def_struct {
($name:ident) => {
pub struct $name;
};
($name:ident $body:tt) => {
pub struct $name $body
}
}
def_struct!(X {}); // compiles
def_struct!(Y); // compiles
fn main() {}
But this is not very clean and gets even harder in more complicated macros. Is there any reason for such behaviour or is it a bug and it would be possible to allow macro to generate unit structs that are not followed by a semicolon, just like any other?