macros-code-review

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Macros Code Review

Rust宏代码审查

Review Workflow

审查工作流程

  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)
  2. Check macro type -- Determine if reviewing declarative (
    macro_rules!
    ), function-like proc macro, attribute macro, or derive macro
  3. 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
  4. Scan macro definitions -- Read full macro bodies including all match arms, not just the invocation site
  5. Check each category -- Work through the checklist below, loading references as needed
  6. Verify before reporting -- Load
    beagle-rust:review-verification-protocol
    before submitting findings
  1. 检查
    Cargo.toml
    ——注意Rust版本(2024版保留
    gen
    关键字,会影响宏输出)、过程宏 crate 依赖(
    syn
    quote
    proc-macro2
    )以及特性标志(例如,启用最小特性集的
    syn
  2. 检查宏类型——确定要审查的是声明式宏(
    macro_rules!
    )、函数式过程宏、属性宏还是派生宏
  3. 判断是否需要宏——如果转换是基于类型的,泛型更合适。宏适用于泛型无法表达的结构化/重复性代码生成场景
  4. 扫描宏定义——阅读完整的宏体,包括所有匹配分支,而不仅仅是调用位置
  5. 检查各分类项——按照下方清单逐一检查,必要时参考相关文档
  6. 报告前验证——提交发现的问题前,先遵循
    beagle-rust:review-verification-protocol
    进行验证

Output Format

输出格式

Report findings as:
text
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
按以下格式报告问题:
text
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.

Quick Reference

快速参考

Issue TypeReference
Fragment types, repetition, hygiene, declarative patternsreferences/declarative-macros.md
Proc macro types, syn/quote, spans, testingreferences/procedural-macros.md
问题类型参考文档
片段类型、重复模式、卫生性、声明式宏模式references/declarative-macros.md
过程宏类型、syn/quote、代码跨度、测试references/procedural-macros.md

Review Checklist

审查清单

Declarative Macros (
macro_rules!
)

声明式宏(
macro_rules!

  • Correct fragment types used (
    :expr
    vs
    :tt
    vs
    :ident
    -- wrong choice causes unexpected parsing)
  • 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 (
    #[macro_export]
    ) use
    $crate::
    for crate-internal paths, never
    crate::
    or
    self::
  • Standard library paths use
    ::core::
    and
    ::alloc::
    (not
    ::std::
    ) for
    no_std
    compatibility
  • compile_error!
    used for meaningful error messages on invalid input patterns
  • Macro placement respects textual scoping (defined before use) unless
    #[macro_export]
  • 使用了正确的片段类型(
    :expr
    vs
    :tt
    vs
    :ident
    ——错误选择会导致解析异常)
  • 重复分隔符与预期语法匹配(
    ,
    vs
    ;
    或无分隔符,
    *
    vs
    +
  • 处理了尾随逗号/分号(在重复模式末尾添加
    $(,)?
    $(;)?
  • 匹配分支按从最具体到最不具体的顺序排列(第一个匹配项优先)
  • 无歧义展开——每个元变量在转换器中出现在正确的重复层级
  • 宏中定义的变量使用宏内部名称(卫生性保护变量,但不保护类型/模块/函数)
  • 导出宏(
    #[macro_export]
    )对 crate 内部路径使用
    $crate::
    ,绝不使用
    crate::
    self::
  • 标准库路径使用
    ::core::
    ::alloc::
    (而非
    ::std::
    )以兼容
    no_std
    环境
  • 对无效输入模式使用
    compile_error!
    生成有意义的错误信息
  • 宏的位置符合文本作用域规则(除非使用
    #[macro_export]
    ,否则需在使用前定义)

Procedural Macros

过程宏

  • syn
    features minimized (don't enable
    full
    when
    derive
    suffices -- reduces compile time)
  • Spans propagated from input tokens to output tokens (errors point to user code, not macro internals)
  • Span::call_site()
    used for identifiers that should be visible to the caller
  • Span::mixed_site()
    used for identifiers private to the macro (matches
    macro_rules!
    hygiene)
  • Error reporting uses
    syn::Error
    with proper spans, not
    panic!
  • Multiple errors collected and reported together via
    syn::Error::combine
  • proc-macro2
    used for testing (testable outside of compiler context)
  • Generated code volume is proportionate -- proc macros that emit large amounts of code bloat compile times
  • syn
    特性集已最小化(当
    derive
    足够时不要启用
    full
    ——减少编译时间)
  • 代码跨度从输入令牌传播到输出令牌(错误指向用户代码而非宏内部)
  • 对调用者可见的标识符使用
    Span::call_site()
  • 宏私有标识符使用
    Span::mixed_site()
    (与
    macro_rules!
    卫生性匹配)
  • 使用带正确跨度的
    syn::Error
    进行错误报告,而非
    panic!
  • 通过
    syn::Error::combine
    收集并一起报告多个错误
  • 使用
    proc-macro2
    进行测试(可在编译器上下文之外测试)
  • 生成的代码量合理——生成大量代码的过程宏会导致编译时间膨胀

Derive Macros

派生宏

  • Derivation is obvious -- a developer could guess what it does from the trait name alone
  • Helper attributes (
    #[serde(skip)]
    style) are documented
  • Trait implementation is correct for all variant shapes (unit, tuple, struct variants)
  • Generated
    impl
    blocks use fully qualified paths (
    ::core::
    ,
    $crate::
    )
  • 派生行为清晰——开发者仅从 trait 名称就能猜到其作用
  • 辅助属性(类似
    #[serde(skip)]
    的风格)已文档化
  • 对所有变体形状(单元变体、元组变体、结构体变体)的 trait 实现正确
  • 生成的
    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 (
    #[test_case]
    style) produce unique test names
  • Framework annotations document what code they generate
  • 输入项被保留或有意转换(未意外丢弃)
  • 属性参数已验证并提供清晰的错误信息
  • 测试生成模式(类似
    #[test_case]
    的风格)生成唯一的测试名称
  • 框架注解说明了其生成的代码内容

Edition 2024 Awareness

2024版本注意事项

  • Macro output does not use
    gen
    as an identifier (reserved keyword -- use
    r#gen
    or rename)
  • Generated
    unsafe fn
    bodies use explicit
    unsafe {}
    blocks around unsafe ops
  • Generated
    extern
    blocks use
    unsafe extern
  • 宏输出未将
    gen
    用作标识符(该关键字已被保留——使用
    r#gen
    或重命名)
  • 生成的
    unsafe fn
    体在不安全操作周围使用显式
    unsafe {}
  • 生成的
    extern
    块使用
    unsafe extern

Generics vs Macros

泛型 vs 宏

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
    const fn
    cannot express
当使用泛型或 trait 约束可实现相同效果时,标记该宏。以下场景适合使用宏:
  • 生成的代码结构不同(不仅仅是类型不同)
  • 为多个具体类型实现重复的 trait
  • 带配置变体的测试套件
  • const fn
    无法表达的编译时计算

Severity Calibration

严重程度校准

Critical (Block Merge)

严重(阻止合并)

  • Macro generates unsound
    unsafe
    code
  • Hygiene violation in macro that outputs
    unsafe
    blocks (caller's variables leak into unsafe context)
  • Proc macro panics instead of returning
    compile_error!
    (crashes the compiler)
  • Derive macro generates incorrect trait implementation (violates trait contract)
  • 宏生成不安全的
    unsafe
    代码
  • 宏中的卫生性违规导致
    unsafe
    块输出(调用者的变量泄漏到不安全上下文)
  • 过程宏触发
    panic!
    而非返回
    compile_error!
    (导致编译器崩溃)
  • 派生宏生成错误的 trait 实现(违反 trait 契约)

Major (Should Fix)

主要(应修复)

  • Exported macro uses
    crate::
    or
    self::
    instead of
    $crate::
    (breaks for downstream users)
  • Exported macro uses
    ::std::
    instead of
    ::core::
    /
    ::alloc::
    (breaks
    no_std
    users)
  • Wrong fragment type causing unexpected parsing (
    :expr
    where
    :tt
    needed, or vice versa)
  • Proc macro enables
    syn
    full features unnecessarily (compile time cost)
  • Missing span propagation (errors point to macro definition, not invocation)
  • No error handling in proc macro (panics on bad input instead of
    compile_error!
    )
  • 导出宏使用
    crate::
    self::
    而非
    $crate::
    (对下游用户造成破坏)
  • 导出宏使用
    ::std::
    而非
    ::core::
    /
    ::alloc::
    (破坏
    no_std
    用户的兼容性)
  • 错误的片段类型导致解析异常(需要
    :tt
    时使用了
    :expr
    ,反之亦然)
  • 过程宏不必要地启用了
    syn
    的全特性集(增加编译时间成本)
  • 缺少代码跨度传播(错误指向宏定义而非调用位置)
  • 过程宏无错误处理(遇到无效输入时触发
    panic!
    而非
    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
    compile_error!
    fallback arm for invalid patterns
  • Helper attributes undocumented
  • 重复模式中缺少对尾随逗号/分号的兼容处理
  • 匹配分支未按最具体到最不具体的顺序排列
  • 在泛型更清晰且表达能力相同的场景下使用了宏
  • 无效模式缺少
    compile_error!
    回退分支
  • 辅助属性未文档化

Informational (Note Only)

信息性(仅作备注)

  • Suggestions to split complex
    macro_rules!
    into a proc macro
  • Suggestions to reduce generated code volume
  • TT munching or push-down accumulation patterns that could be simplified
  • 建议将复杂的
    macro_rules!
    拆分为过程宏
  • 建议减少生成的代码量
  • 可简化的TT咀嚼(TT munching)或下推累积模式

Valid Patterns (Do NOT Flag)

有效模式(无需标记)

  • macro_rules!
    for test batteries
    -- Generating repetitive test modules from a list of types/configs
  • macro_rules!
    for trait impls
    -- Implementing a trait for many concrete types with identical bodies
  • TT munching -- Valid advanced pattern for recursive token processing
  • Push-down accumulation -- Valid pattern for building output incrementally across recursive calls
  • #[macro_export]
    with
    $crate
    -- Correct way to make macros usable outside the defining crate
  • Span::call_site()
    for generated functions
    -- Intentionally making generated items visible to callers
  • syn::Error::to_compile_error()
    -- Correct error reporting pattern in proc macros
  • trybuild
    tests for proc macros
    -- Standard compile-fail testing approach
  • Attribute macros on test functions -- Common pattern for test setup/teardown
  • compile_error!
    in impossible match arms
    -- Good practice for catching invalid macro input
  • 用于测试套件的
    macro_rules!
    ——从类型/配置列表生成重复的测试模块
  • 用于 trait 实现的
    macro_rules!
    ——为多个具体类型实现具有相同体的 trait
  • TT咀嚼(TT munching)——用于递归令牌处理的有效高级模式
  • 下推累积——在递归调用中逐步构建输出的有效模式
  • $crate
    #[macro_export]
    ——使宏能在定义 crate 外使用的正确方式
  • 为生成函数使用
    Span::call_site()
    ——有意让生成的项对调用者可见
  • syn::Error::to_compile_error()
    ——过程宏中正确的错误报告模式
  • 为过程宏使用
    trybuild
    测试
    ——标准的编译失败测试方法
  • 测试函数上的属性宏——用于测试前置/后置处理的常见模式
  • 不可能匹配分支中的
    compile_error!
    ——捕获无效宏输入的良好实践

Before Submitting Findings

提交问题前

Load and follow
beagle-rust:review-verification-protocol
before reporting any issue.
报告任何问题前,请加载并遵循
beagle-rust:review-verification-protocol