I want to create a macro generating a given formatter (Display
, Debug
,...) for a struct containing a single generic type.
macro_rules! create_formatter {
($type_name:ident<$gen_param:ident>, $trait:path) => {
impl<$gen_param: $trait> $trait for $type_name<$gen_param> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
// isn't yet implemented
}
}
};
}
When I call the macro later in the code (create_formatter!(MyStruct<T>, std::fmt::Display);
), the compiler gives the following feedback:
error: expected one of `,`, `=`, `>`, or `?`, found `std::fmt::Display`
--> test.rs:6:26
|
6| impl<$gen_param: $trait> $trait for $type_name<$gen_param> {
| ^^^^^^^^
What am I doing wrong?
Rust has excellent support for macros. Macros enable you to write code that writes other code, which is known as metaprogramming. Macros provide functionality similar to functions but without the runtime cost. There is some compile-time cost, however, since macros are expanded during compile time.
impl: An impl is an implementation block that has the keyword “impl” followed by the same name as that of the struct. It is used to comprise methods, and functions. A struct is allowed to have multiple impl blocks.
This does seem mysterious! It seems the problem is down to the way that the output of a macro is parsed: since it's been partly pre-parsed as a path
during the macro processing, it no longer matches the parse rule for a trait bound. There was a bug raised a few weeks ago about this.
However, there is good news - it's been fixed! The example actually works in the beta or nightly compilers (playground), though note I had to rename $trait
to $t
as trait
is a keyword.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With