← ClaudeAtlas

rust-macroslisted

Write a macro only when a function, a trait, or a generic cannot do the job — then by-example before proc-macro, with hygiene, a `_private` helper module, and spanned compile errors instead of panics. Use when writing or reviewing macro_rules! or a proc macro, when a derive or attribute macro is being added, when macro hygiene or `$crate` comes up, or when the user asks whether something should be a macro.
rewrite-rs/skills · ★ 2 · Code & Development · score 73
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