Saltar a contenido

Week 15 - Declarative Macros (macro_rules!)

15.1 Conceptual Core

  • macro_rules! is a pattern-matching macro system operating on token trees. It is hygienic by default-identifiers introduced in the macro do not collide with identifiers in the call site (with subtle exceptions you must learn).
  • Designators: expr, ident, ty, pat, tt, block, stmt, path, meta, vis, lifetime, literal, item. Each constrains what tokens the matcher accepts and how they may be re-emitted.
  • Repetition: $( ... )*, $( ... )+, $( ... ),*. The macro author is responsible for handling empty/non-empty cases.

15.2 Mechanical Detail

  • Hygiene exceptions: $crate is the canonical way to refer to the defining crate. Without it, vec![1,2,3] would break if the user shadowed std::vec. Use $crate:: in every path emitted by a macro.
  • Recursion: macros may invoke themselves. The recursion limit is #![recursion_limit = "256"] by default-raise it explicitly if needed (and document why).
  • TT munching: a pattern where the macro consumes tokens one at a time recursively. The standard idiom for parsing custom DSLs in macro_rules!.
  • Re-export discipline: #[macro_export] makes a macro visible at the crate root. The 2018+ edition allows pub use of macros, which is the modern preferred path.

15.3 Lab-"A hashmap! Macro With Diagnostics"

Implement a hashmap! macro: - hashmap! { "a" => 1, "b" => 2 } produces a HashMap. - Trailing comma allowed. - Type-checks: a typo like hashmap! { "a" => 1, "b" -> 2 } should produce a useful error pointing at the bad token (use compile_error! strategically). - Pre-allocates with HashMap::with_capacity.

15.4 Idiomatic & Clippy Drill

  • clippy::crate_in_macro_def (use $crate::), clippy::single_call_fn, clippy::useless_format. Read the Little Book of Rust Macros sections on hygiene and TT munching.

15.5 Production Hardening Slice

  • Add cargo-expand to your dev tooling. Inspect the expansion of every macro you ship; commit a sample expansion as a doctest. This is your guard against silent semantic drift in macro maintenance.

Comments