I'm trying to write a Rust macro that expands to an enum whose variants contain data of types that need lifetime annotations and the compiler won't let me.
I've boiled the problem down to this minimal example:
struct A<'a> {
s: &'a str
}
macro_rules! my_macro {
( $ty:ty ) => {
enum E<'a> {
M($ty<'a>)
}
}
}
my_macro!(A);
As you can see, this is meant to write out an enum E
with a variant M
that contains data whose type is taken from the macro parameters and is given a lifetime parameter of 'a
. But trying to compile it yields a bunch of errors I find strange (I've shortened them a bit from the compiler's exact output):
error: lifetime in trait object type must be followed by `+` --> src/lib.rs:8:19
|
8 | M($ty<'a>)
| ^^
...
13 | my_macro!(A);
| ------------ in this macro invocation
|
= note: this error originates in the macro `my_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: expected one of `)` or `,`, found `<` --> src/lib.rs:8:18
|
8 | M($ty<'a>)
| ^
| expected one of `)` or `,`
| help: missing `,`
error: expected one of `)`, `+`, or `,`, found `>` --> src/lib.rs:8:21
|
8 | M($ty<'a>)
| ^ expected one of `)`, `+`, or `,`
I don't get this at all: What trait object? There isn't one as far as I can tell.
Also, replacing M($ty<'a>)
with a variant definition that doesn't use the macro type variable $ty
, e.g. M(A<'a>)
, makes it work fine.
How can I make sense of the compiler's complaint and how can I write a macro producing the kind of enum I want?