Overview
cargo expand prints a crate's source after macro expansion — every derive, every
attribute macro, every macro_rules! invocation replaced by the code it generates,
pretty-printed and syntax-highlighted. In an ecosystem where serde, tokio, sqlx, tonic,
axum and half of every dependency tree work by generating code, this is the tool that
turns "magic attribute" into "oh, that's all it does" — both for debugging weird errors
and for learning how the libraries actually work.
Key points
- Install once, use forever:
cargo install cargo-expand; it drives nightly rustc's-Zunpretty=expandedunder the hood, so a nightly toolchain must be installed (the project itself can stay on stable — it invokescargo +nightlyinternally). - Scope the expansion:
cargo expand path::to::moduleorcargo expand --test integration some_test— full-crate output on a real project is thousands of lines; always narrow to the item you're debugging. - The classic uses: seeing what
#[derive(Serialize)]does with your#[serde(...)]attributes, what#[tokio::main]wraps aroundmain, why a#[sqlx::test]or#[tracing::instrument]interacts badly with another attribute, and what your ownmacro_rules!actually produced. - Expansion is pre-type-check: expanded output may still not compile — macros can emit code that later phases reject; expand shows what was generated, the compiler error explains why it's wrong.
- For proc-macro authors the complements are
cargo expandon a consumer crate plustrybuild(compile-fail tests) andproc-macro2/syn'scargo expand-friendly output — see Unit testing. - rust-analyzer's "Expand macro recursively" covers the quick inline case; cargo-expand remains the tool for whole-module views and pipelines (diffing expansions across versions).
Examples
cargo expand models::user # one module
cargo expand --lib --features postgres # expansion under a feature set
cargo expand --test api_tests create_user
Related
- The Rust toolchain — parent catalog.
- rustc — the expansion phase this exposes.
- rust-analyzer — the inline expansion view for quick checks.
- Deep dive Rust — the macro system in the language's overall model.