Skills macros-code-review
Reviews Rust macro code for hygiene issues, fragment misuse, compile-time impact, and procedural macro patterns. Use when reviewing macro_rules! definitions, procedural macros, derive macros, or attribute macros.
install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/anderskev/macros-code-review" ~/.claude/skills/openclaw-skills-macros-code-review && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/anderskev/macros-code-review" ~/.openclaw/skills/openclaw-skills-macros-code-review && rm -rf "$T"
manifest:
skills/anderskev/macros-code-review/SKILL.mdsource content
Macros Code Review
Review Workflow
- Check
-- Note Rust edition (2024 reservesCargo.toml
keyword, affecting macro output), proc-macro crate dependencies (gen
,syn
,quote
), and feature flags (e.g.,proc-macro2
with minimal features)syn - Check macro type -- Determine if reviewing declarative (
), function-like proc macro, attribute macro, or derive macromacro_rules! - Check if a macro is needed -- If the transformation is type-based, generics are better. Macros are for structural/repetitive code generation that generics cannot express
- Scan macro definitions -- Read full macro bodies including all match arms, not just the invocation site
- Check each category -- Work through the checklist below, loading references as needed
- Verify before reporting -- Load
before submitting findingsbeagle-rust:review-verification-protocol
Output Format
Report findings as:
[FILE:LINE] ISSUE_TITLE Severity: Critical | Major | Minor | Informational Description of the issue and why it matters.
Quick Reference
| Issue Type | Reference |
|---|---|
| Fragment types, repetition, hygiene, declarative patterns | references/declarative-macros.md |
| Proc macro types, syn/quote, spans, testing | references/procedural-macros.md |
Review Checklist
Declarative Macros (macro_rules!
)
macro_rules!- Correct fragment types used (
vs:expr
vs:tt
-- wrong choice causes unexpected parsing):ident - Repetition separators match intended syntax (
vs,
vs none,;
vs*
)+ - Trailing comma/semicolon handled (add
or$(,)?
at end of repetition)$(;)? - Matchers ordered from most specific to least specific (first match wins)
- No ambiguous expansions -- each metavariable appears in the correct repetition depth in the transcriber
- Variables defined in the macro use macro-internal names (hygiene protects variables, not types/modules/functions)
- Exported macros (
) use#[macro_export]
for crate-internal paths, never$crate::
orcrate::self:: - Standard library paths use
and::core::
(not::alloc::
) for::std::
compatibilityno_std -
used for meaningful error messages on invalid input patternscompile_error! - Macro placement respects textual scoping (defined before use) unless
#[macro_export]
Procedural Macros
-
features minimized (don't enablesyn
whenfull
suffices -- reduces compile time)derive - Spans propagated from input tokens to output tokens (errors point to user code, not macro internals)
-
used for identifiers that should be visible to the callerSpan::call_site() -
used for identifiers private to the macro (matchesSpan::mixed_site()
hygiene)macro_rules! - Error reporting uses
with proper spans, notsyn::Errorpanic! - Multiple errors collected and reported together via
syn::Error::combine -
used for testing (testable outside of compiler context)proc-macro2 - Generated code volume is proportionate -- proc macros that emit large amounts of code bloat compile times
Derive Macros
- Derivation is obvious -- a developer could guess what it does from the trait name alone
- Helper attributes (
style) are documented#[serde(skip)] - Trait implementation is correct for all variant shapes (unit, tuple, struct variants)
- Generated
blocks use fully qualified paths (impl
,::core::
)$crate::
Attribute Macros
- Input item is preserved or intentionally transformed (not accidentally dropped)
- Attribute arguments are validated with clear error messages
- Test generation patterns (
style) produce unique test names#[test_case] - Framework annotations document what code they generate
Edition 2024 Awareness
- Macro output does not use
as an identifier (reserved keyword -- usegen
or rename)r#gen - Generated
bodies use explicitunsafe fn
blocks around unsafe opsunsafe {} - Generated
blocks useexternunsafe extern
Generics vs Macros
Flag a macro when the same result is achievable with generics or trait bounds. Macros are appropriate when:
- The generated code varies structurally (not just by type)
- Repetitive trait impls for many concrete types
- Test batteries with configuration variants
- Compile-time computation that
cannot expressconst fn
Severity Calibration
Critical (Block Merge)
- Macro generates unsound
codeunsafe - Hygiene violation in macro that outputs
blocks (caller's variables leak into unsafe context)unsafe - Proc macro panics instead of returning
(crashes the compiler)compile_error! - Derive macro generates incorrect trait implementation (violates trait contract)
Major (Should Fix)
- Exported macro uses
orcrate::
instead ofself::
(breaks for downstream users)$crate:: - Exported macro uses
instead of::std::
/::core::
(breaks::alloc::
users)no_std - Wrong fragment type causing unexpected parsing (
where:expr
needed, or vice versa):tt - Proc macro enables
full features unnecessarily (compile time cost)syn - Missing span propagation (errors point to macro definition, not invocation)
- No error handling in proc macro (panics on bad input instead of
)compile_error!
Minor (Consider Fixing)
- Missing trailing comma/semicolon tolerance in repetition patterns
- Matcher arms not ordered most-specific-first
- Macro used where generics would be clearer and equally expressive
- Missing
fallback arm for invalid patternscompile_error! - Helper attributes undocumented
Informational (Note Only)
- Suggestions to split complex
into a proc macromacro_rules! - Suggestions to reduce generated code volume
- TT munching or push-down accumulation patterns that could be simplified
Valid Patterns (Do NOT Flag)
for test batteries -- Generating repetitive test modules from a list of types/configsmacro_rules!
for trait impls -- Implementing a trait for many concrete types with identical bodiesmacro_rules!- TT munching -- Valid advanced pattern for recursive token processing
- Push-down accumulation -- Valid pattern for building output incrementally across recursive calls
with#[macro_export]
-- Correct way to make macros usable outside the defining crate$crate
for generated functions -- Intentionally making generated items visible to callersSpan::call_site()
-- Correct error reporting pattern in proc macrossyn::Error::to_compile_error()
tests for proc macros -- Standard compile-fail testing approachtrybuild- Attribute macros on test functions -- Common pattern for test setup/teardown
in impossible match arms -- Good practice for catching invalid macro inputcompile_error!
Before Submitting Findings
Load and follow
beagle-rust:review-verification-protocol before reporting any issue.