Macros Best Practices
Prefer functions, generics, and traits; reach for macros when syntax or codegen demands it. Good macros have great errors, tests, and documented input grammar.
Busca en todas las páginas de la documentación
Prefer functions, generics, and traits; reach for macros when syntax or codegen demands it. Good macros have great errors, tests, and documented input grammar.
macro_rules! or proc-macro crate.fn, const fn, trait, impl first. Better errors and IDE support.macro_rules! for repetitive syntax only. Not for business logic.proc-macro = true crate. Keep syn off runtime dependency graph.syn::Error::new_spanned for diagnostics. Point at user's token, not macro internals.split_for_impl. Derives must work on struct Foo<T>.#[allow] or pub.$crate:: paths in exported macro_rules!. Correct resolver from consumer crate.cargo expand snapshots for non-trivial macros. Checked in CI via macrotest or manual review.trybuild compile-fail tests for invalid input. Lock error messages.proc_macro2. Without full compiler driver.eprintln! debug behind feature or env. No noisy builds for users.build.rs if needed.syn/quote versions consciously. Workspace alignment reduces duplicate syn.unsafe in generated code like hand-written unsafe. Macro does not absolve review.Vec-like literals, small assert helpers, repetitive match arms - not whole ORMs.
Usually separate publishable macro crate even if internal monorepo member.
As needed; keep related derives together; split if compile time hurts consumers.
Prefer safe expansion; if unsafe required, document invariants in emitted docs.
Yes for frameworks; still offer non-macro builder path when feasible for IDE users.
Path resolution and use preludes; test expand under 2024 consumer crate.
Workshop: expand serde derive, write tiny derive, debug with trybuild.
Plan escape hatch: generated code pattern stable enough to hand-write if removing macro.
Clippy lints apply to expansion; fix generator not allow everywhere.
Show expansion examples in docs; doc_cfg for feature-gated macro paths.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026