liveBook · Manning

Cargo-expand

As explained in Write Powerful Rust Macros

cargo expand is a Cargo subcommand that displays the Rust source code produced by macro expansion.

cargo expand is a Cargo subcommand that prints an application’s Rust source after macro expansion. Install it with cargo install cargo-expand, then run cargo expand from the application root or src directory. section 3.5

Use cargo expand to:

  • Visually inspect generated implementations and expanded macros, including standard macros such as println!. section 3.5
  • Investigate compilation failures that cargo check inside the macro library cannot reveal. section 3.9 section 7.8.2
  • Redirect output to a file or temporarily compile the expanded source to obtain more precise IDE and cargo check diagnostics. section 3.5

Debugging a generated builder

When a builder macro produces an error such as “expected value, found struct,” run cargo expand --tests --bin builder-usage inside the consuming application. Inspecting the generated builder and build method can reveal missing braces, return types, or malformed identifiers. A compile test then verifies that the generated code compiles. section 6.4.1

Listing 3.10 cargo expand output (with changed formatting)
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;       #1

// imports

struct Example;            #2

impl Example { #3
    fn hello_world(&self) {
        {
            ::std::io::_print( #4
                format_args!("Hello, World\n")
            );            
        }
    }
}               

// Pet enum and its expanded code

// main function

Inspect a representative expansion showing generated implementations and the lower-level code emitted for println!. section 3.5

How Write Powerful Rust Macros covers it

How deep it goes
Shows expanded source and supports test-specific expansion, but leaves format_args! unexpanded and does not replace compile-time testing.
Examples
Uses expanded Hello World code, a malformed panic-to-result macro, and a builder macro expanded with tests.
What it assumes
Assumes working Rust and Cargo knowledge while teaching how generated code differs from code checked inside a macro library.
What you can do after
Diagnose/debug with cargo expand by inspecting generated code, redirecting output, and checking consuming applications or tests.
How it connects
Connects procedural macros, macro expansion, generated code, cargo check, compiler diagnostics, and compile testing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Write Powerful Rust Macros. The section links point to the parts of the book it draws on.