Help us improve
Share bugs, ideas, or general feedback.
From beagle-rust
Reviews Rust macro code for hygiene issues, fragment misuse, compile-time impact, and procedural macro patterns. Used for macro_rules!, proc-macro, derive, or attribute macro review.
npx claudepluginhub existential-birds/beagle --plugin beagle-rustHow this skill is triggered — by the user, by Claude, or both
Slash command
/beagle-rust:macros-code-reviewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
1. **Check `Cargo.toml`** -- Note Rust edition (2024 reserves `gen` keyword, affecting macro output), proc-macro crate dependencies (`syn`, `quote`, `proc-macro2`), and feature flags (e.g., `syn` with minimal features)
Verifies code review findings using a multi-step protocol to reduce false positives. Includes Rust-specific checks for edition, dead code, and trait impls.
Audits Rust code for unsafe blocks, ownership and borrowing patterns, concurrency issues, error handling, and Cargo dependency vulnerabilities.
Applies Clippy lint categories for Rust code including correctness, performance, style, and custom lint configuration. Useful for Rust code quality checks.
Share bugs, ideas, or general feedback.
Cargo.toml -- Note Rust edition (2024 reserves gen keyword, affecting macro output), proc-macro crate dependencies (syn, quote, proc-macro2), and feature flags (e.g., syn with minimal features)macro_rules!), function-like proc macro, attribute macro, or derive macroComplete in order. Do not emit findings until Gate 4 passes for each issue.
Gate 1 — Crate context (on disk)
PASS when: You opened the reviewed crate’s Cargo.toml (workspace member path if applicable) and recorded Rust edition, whether the crate is proc-macro = true, and relevant proc-macro dependencies or syn / quote feature flags.
Blocks rationalization: Edition 2024 findings (gen, unsafe extern, generated unsafe bodies) and syn “full” vs minimal flags require this — do not flag edition-specific macro output without matching edition from the file.
Gate 2 — Macro definitions read
PASS when: For every macro you critique, you read the full definition (all macro_rules! arms, or the proc-macro entry plus helpers you rely on), not only call sites or partial expansions.
Artifact: At least one path per macro to the defining .rs file(s) you used.
Gate 3 — Per-finding evidence
PASS when: Each planned issue has [FILE:LINE] from the current tree for the macro definition, attribute/derive site, or generated code location you are discussing (not from memory, docs-only, or another branch).
Gate 4 — Pre-report protocol
PASS when: You loaded and applied beagle-rust:review-verification-protocol, including Macro-Specific Verification for hygiene, fragment type, and proc-macro performance claims. Then add findings.
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
| Issue Type | Reference |
|---|---|
Fragment types, repetition, hygiene boundaries (vars vs types), $crate paths, TT-muncher pattern + recursion limits, fragment-matcher follow restrictions, decl-vs-proc decision tree | references/declarative-macros.md |
Proc macro types, syn/quote, span hygiene (call_site vs def_site vs mixed_site), syn::Error::new_spanned + combine, parse_quote! vs quote!, syn feature audit, trybuild UI tests | references/procedural-macros.md |
macro_rules!):expr vs :tt vs :ident -- wrong choice causes unexpected parsing), vs ; vs none, * vs +)$(,)? or $(;)? at end of repetition)#[macro_export]) use $crate:: for crate-internal paths, never crate:: or self::::core:: and ::alloc:: (not ::std::) for no_std compatibilitycompile_error! used for meaningful error messages on invalid input patterns#[macro_export]syn features minimized (don't enable full when derive suffices -- reduces compile time)Span::mixed_site() is the default for introduced helper variables — call_site only when intentionally pointing at user code; def_site is nightly-only on proc_macro::Spansyn::Error::new_spanned(node, msg) with the offending AST node, never panic!syn::Error::combine (good UX vs first-failure)parse_quote! (not quote!) used when the result needs to be a syn::T for further AST manipulation; syn::parse2(quote!{...}) for fallible casesproc_macro2, not proc_macro (compatibility with downstream consumers)proc-macro2 used for testing (testable outside of compiler context)#[serde(skip)] style) are documentedimpl blocks use fully qualified paths (::core::, $crate::)#[test_case] style) produce unique test namesgen as an identifier (reserved keyword -- use r#gen or rename)unsafe fn bodies use explicit unsafe {} blocks around unsafe opsextern blocks use unsafe externFlag a macro when the same result is achievable with generics or trait bounds. Macros are appropriate when:
const fn cannot expressunsafe codeunsafe blocks (caller's variables leak into unsafe context)compile_error! (crashes the compiler)crate:: or self:: instead of $crate:: (breaks for downstream users)::std:: instead of ::core::/::alloc:: (breaks no_std users):expr where :tt needed, or vice versa)syn full features unnecessarily (compile time cost)compile_error!)compile_error! fallback arm for invalid patternsmacro_rules! into a proc macromacro_rules! 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 bodies#[macro_export] with $crate -- Correct way to make macros usable outside the defining crateSpan::call_site() for generated functions -- Intentionally making generated items visible to callerssyn::Error::to_compile_error() -- Correct error reporting pattern in proc macrostrybuild tests for proc macros -- Standard compile-fail testing approachcompile_error! in impossible match arms -- Good practice for catching invalid macro input