rust-macroslisted
Install: claude install-skill rewrite-rs/skills
# Rust Macros
The first question a macro must answer is why it is not a function, a trait,
or a generic — and usually the answer is that it is not.
## A macro is a last resort
Most macros exist to avoid typing, and the cost they charge is paid by every
reader afterwards: no jump-to-definition worth the name, error messages
pointing at expansions, no type checking until the expansion happens. The
genuine answers are three — a variadic interface, generating an impl per
type from a list, and a DSL whose syntax is not Rust. Name the case; if it
is not one of the three, reach for the non-macro and say which.
## By-example before procedural
`macro_rules!` is in the same crate, needs no dependency, and can be read. A
proc macro needs its own crate, a `syn`/`quote` dependency pair, and compiles
before the crate that uses it. Reach for it when the input has to be parsed
as Rust syntax — what derives and attribute macros are — and not before.
## Hygiene, and `$crate`
A macro expands at the call site, where the names it mentions may mean
something else. `$crate` resolves to the defining crate no matter where the
expansion lands, and a macro that names any item from its own crate without
it works only until someone invokes it from a module that shadows the path.
Local variables a `macro_rules!` introduces are hygienic and cannot collide;
paths and types are not.
## Fragment specifiers say what you accept
`expr`, `ty`, `ident`, `pat`, `literal`, `tt` — pick the narrowest that fit