::macro_rules_attribute
Use declarative macros as proc_macro attributes or derives.
Motivation
macro_rules!
macros can be extremely powerful, but their call-site ergonomics
are sometimes not great, especially when decorating item definitions.
Indeed, compare:
-
# foo!
-
#
-
The former does not scale well, since it leads to rightward drift and "excessive" braces.
-
But on the other hand, the latter requires setting up a dedicated crate for the compiler, a
proc-macro
crate. And 99% of the time this will pull the::syn
and::quote
dependencies, which have a non-negligible compile-time overhead (the first time they are compiled).-
note: these crates are a wonderful piece of technology, and can lead to extremely powerful macros. When the logic of the macro is so complicated that it requires a recursive
tt
muncher when implemented as amacro_rules!
macro, it is definitely time to be using aproc
edural macro.Anything involving
ident
generation / derivation, for instance, will very often requireproc
edural macros, unless it is simple enough for::paste
to handle it.
-
Solution
With the macro_rules_attribute
and macro_rules_derive
attributes, it is
now possible to use proc_macro_attribute
syntax to apply a macro_rules!
macro:
# use macro_rules_attribute;
#
#
without even depending on ::quote
, ::syn
or ::proc-macro2
, for
fast compile times.
Example
Deriving getters for a (non-generic) struct
:
#
# ignore!
) => *
}
)}
use Person;
Debugging
An optional compilation feature, "verbose-expansions"
can be used to print at
compile_time the exact macro call:
[]
= { = "...", = ["verbose-expansions"] }