Skip to content
Subcommand to show result of macro expansion
Branch: master
Clone or download
Latest commit 6989b98 Feb 14, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Parse --color opt Feb 13, 2019
.gitignore Cargo-expand subcommand Jun 5, 2016
.travis.yml Update minimum compiler to 1.32 as required by syn-select Jan 31, 2019
Cargo.lock Release 0.4.9 Feb 13, 2019
LICENSE-APACHE Cargo-expand subcommand Jun 5, 2016
LICENSE-MIT Cargo-expand subcommand Jun 5, 2016 Document configuration file Feb 13, 2019


Build Status Latest Version

Once installed, the following command prints out the result of macro expansion and #[derive] expansion applied to the current crate.

$ cargo expand

This is a wrapper around the more verbose compiler command:

$ cargo rustc --profile=check -- -Zunstable-options --pretty=expanded


Install with cargo install cargo-expand.

This command optionally uses rustfmt to format the expanded output. The resulting code is typically much more readable than what you get from the compiler. If rustfmt is not available, the expanded code is not formatted. Install rustfmt with rustup component add rustfmt.

Cargo expand relies on unstable compiler flags so it requires a nightly toolchain to be installed, though does not require nightly to be the default toolchain or the one with which cargo expand itself is executed. If the default toolchain is one other than nightly, running cargo expand will find and use nightly anyway.


$ cat src/

struct S;

fn main() {
    println!("{:?}", S);

$ cargo expand

use std::prelude::v1::*;
extern crate std as std;
struct S;
impl $crate::fmt::Debug for S {
    fn fmt(&self, f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
        match *self {
            S => {
                let mut debug_trait_builder = f.debug_tuple("S");
fn main() {
            &["", "\n"],
            &match (&S,) {
                (arg0,) => [$crate::fmt::ArgumentV1::new(
            &[$crate::fmt::rt::v1::Argument {
                position: $crate::fmt::rt::v1::Position::At(0usize),
                format: $crate::fmt::rt::v1::FormatSpec {
                    fill: ' ',
                    align: $crate::fmt::rt::v1::Alignment::Unknown,
                    flags: 0u32,
                    precision: $crate::fmt::rt::v1::Count::Implied,
                    width: $crate::fmt::rt::v1::Count::Implied,


See cargo expand --help for a complete list of options, most of which are consistent with other Cargo subcommands. Here are a few that are common in the context of cargo expand.

To expand a particular test target:

$ cargo expand --test test_something

To expand without rustfmt:

$ cargo expand --ugly

To expand a specific module or type or function only:

$ cargo expand path::to::module

cargo expand punctuated::printing cargo expand token::FatArrow


The cargo expand command reads the [expand] section of $CARGO_HOME/config if there is one. Currently the only configuration option is the syntax highlighting theme.

theme = "TwoDark"

Run cargo expand --themes to print a list of available themes. Use theme = "none" to disable coloring.


Be aware that macro expansion to text is a lossy process. This is a debugging aid only. There should be no expectation that the expanded code can be compiled successfully, nor that if it compiles then it behaves the same as the original code.

For instance the following function returns 3 when compiled ordinarily by Rust but the expanded code compiles and returns 4.

fn f() -> i32 {
    let x = 1;

    macro_rules! first_x {
        () => { x }

    let x = 2;

    x + first_x!()

Refer to The Book for more on the considerations around macro hygiene.


Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.