Rust Macros Cheat Sheet
Covers declarative macros with macro_rules!, common built-in macros, and the basics of derive and procedural macros in Rust.
2 PagesAdvancedApr 2, 2026
macro_rules! Basics
Declaring a simple declarative macro with pattern matching.
rust
// A simple declarative macromacro_rules! square { ($x:expr) => { $x * $x };}fn main() { let result = square!(5); // expands to 5 * 5 println!("{}", result);}// Macros can have multiple match arms, like matchmacro_rules! greet { () => { println!("Hello!"); }; ($name:expr) => { println!("Hello, {}!", $name); };}greet!(); // "Hello!"greet!("Ferris"); // "Hello, Ferris!"
Repetition Patterns
Matching a variable number of macro arguments.
rust
// $(...),* repeats zero or more times, comma-separatedmacro_rules! my_vec { ( $( $x:expr ),* ) => { { let mut v = Vec::new(); $( v.push($x); )* v } };}let v = my_vec![1, 2, 3]; // expands to a Vec containing 1, 2, 3// $(...),+ requires one or more repetitionsmacro_rules! my_max { ($x:expr) => { $x }; ($x:expr, $( $rest:expr ),+) => { { let rest_max = my_max!($( $rest ),+); if $x > rest_max { $x } else { rest_max } } };}
Common Built-in Macros
Macros available from the standard library without any imports.
- println! / print!- Formatted output to stdout, with/without trailing newline
- format!- Builds a String using the same formatting syntax as println!
- vec!- Creates a Vec<T> from a list of elements or repeated value/count
- assert! / assert_eq! / assert_ne!- Runtime checks that panic on failure, used heavily in tests
- panic!- Triggers an unrecoverable error with a formatted message
- todo! / unimplemented!- Placeholder macros that panic when reached, useful during development
- matches!- Returns true/false for whether a value matches a given pattern
- dbg!- Prints a value with file/line info to stderr and returns it, for quick debugging
Derive Macros
Using #[derive(...)] to auto-generate trait implementations.
rust
// #[derive(...)] is a procedural macro that generates trait impls at compile time#[derive(Debug, Clone, PartialEq)]struct Point { x: i32, y: i32,}// serde's derive macros (from the `serde` crate) generate serialization code#[derive(serde::Serialize, serde::Deserialize)]struct Config { name: String, retries: u32,}let p1 = Point { x: 1, y: 2 };let p2 = p1.clone();assert_eq!(p1, p2); // works because of #[derive(PartialEq)]println!("{:?}", p1); // works because of #[derive(Debug)]
Fragment Specifiers
Types of syntax a macro_rules! matcher can capture.
- expr- Matches an expression (e.g. 1 + 2, foo())
- ident- Matches an identifier (variable or function name)
- ty- Matches a type (e.g. Vec<i32>)
- block- Matches a brace-delimited block of statements
- pat- Matches a pattern (as used in match arms)
- stmt- Matches a single statement
- tt- Matches a single token tree; the most flexible/general specifier
- literal- Matches a literal value (e.g. "hi", 42, true)
Pro Tip
Reach for a declarative macro_rules! macro first — it's far simpler to write and debug than a procedural macro. Only build a proc macro (in its own crate with proc-macro = true) when you need to generate code from arbitrary Rust syntax, like a custom #[derive(...)].
Was this cheat sheet helpful?
Explore Topics
#RustMacros#RustMacrosCheatSheet#Programming#Advanced#MacroRulesBasics#RepetitionPatterns#CommonBuiltInMacros#DeriveMacros#CheatSheet#SkillVeris