How do I see the expanded macro code that's causing my compile error?

22,742

Solution 1

cargo rustc --profile=check -- -Zunpretty=expanded, but a more concise alternative is the cargo-expand crate. It provides a Cargo subcommand cargo expand which prints the result of macro expansion. It also passes the expanded code through rustfmt which generally results in much more readable code than the default output from rustc.

Install by running cargo install cargo-expand.

Solution 2

Yes, you can pass a special flag to rustc, called --pretty=expanded:

% cat test.rs
fn main() {
    println!("Hello world");
}
% rustc -Z unstable-options --pretty=expanded test.rs
#![feature(no_std)]
#![no_std]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate "std" as std;
fn main() {
    ::std::old_io::stdio::println_args(::std::fmt::Arguments::new_v1({
                                                                         static __STATIC_FMTSTR:
                                                                                &'static [&'static str]
                                                                                =
                                                                             &["Hello world"];
                                                                         __STATIC_FMTSTR
                                                                     },
                                                                     &match ()
                                                                          {
                                                                          ()
                                                                          =>
                                                                          [],
                                                                      }));
}

You need to allow it first, however, by passing -Z unstable-options.

Since Rust 1.1 you can pass these arguments to Cargo, like this:

cargo rustc -- -Z unstable-options --pretty=expanded

Solution 3

Starting with nightly-2021-07-28, one must pass -Zunpretty=expanded instead of -Zunstable-options --pretty=expanded, like this:

% rustc -Zunpretty=expanded test.rs

or:

% cargo rustc -- -Zunpretty=expanded

Relevant rustc commits

The --pretty argument was removed from nightly-2021-07-28 via this commit. Support for -Zunpretty=expanded was added to nightly-2018-01-24 via this commit.

Share:
22,742
Caspar
Author by

Caspar

Principal Engineer at Atlassian

Updated on July 05, 2022

Comments

  • Caspar
    Caspar almost 2 years

    I have a compile error involving a macro:

    <mdo macros>:6:19: 6:50 error: cannot move out of captured outer variable in an `FnMut` closure
    <mdo macros>:6 bind ( $ e , move | $ p | mdo ! { $ ( $ t ) * } ) ) ; (
                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    <mdo macros>:1:1: 14:36 note: in expansion of mdo!
    <mdo macros>:6:27: 6:50 note: expansion site
    <mdo macros>:1:1: 14:36 note: in expansion of mdo!
    <mdo macros>:6:27: 6:50 note: expansion site
    <mdo macros>:1:1: 14:36 note: in expansion of mdo!
    src/parser.rs:30:42: 37:11 note: expansion site
    error: aborting due to previous error
    

    Unfortunately, the macro is recursive so it's hard to figure out what the compiler is complaining about, plus it seems like the line numbers are for the expanded macro rather than my code.

    How can I see the expanded macro? Is there a flag I can pass to rustc (or even better, cargo) to dump this out?

    (This macro is from rust-mdo, though I don't think it matters.)

  • lncr
    lncr almost 7 years
    As of 1.19 this command cargo rustc -- -Z unstable-options --pretty=expanded is now only available on nightly.
  • Bogdan Mart
    Bogdan Mart over 5 years
    Why it's only in nightly?(
  • grooveplex
    grooveplex almost 5 years
    @BogdanMart Because it uses an unstable option, but fear not, you can easily use it. Run rustup install nightly, then rustup run nightly cargo rustc -- -Z unstable-options --pretty=expanded.
  • Squirrel
    Squirrel about 4 years
    cargo install cargo-expand —features=prettyprint/regex-fancy will be slightly slower but avoids a c++ dependency so is more likely to build cleanly.
  • dtolnay
    dtolnay about 4 years
    cargo-expand does not depend on prettyprint or any C++ dependencies.
  • jhfrontz
    jhfrontz almost 4 years
    So, for three (and counting) years, this capability has never been "stabilized"?
  • Tumbleweed53
    Tumbleweed53 over 3 years
    Likely less about stabilization and more that they don't want to commit to supporting it.
  • Alex Huszagh
    Alex Huszagh about 3 years
    @jhfrontz A lot of functionality isn't stabilized, because it means it's always available even if they deprecate it, and isn't meant to be used except as a debugging or internal feature. -Z timings, -Z unstable-options --pretty=expanded, most rustfmt lints are all nightly only.
  • SharedRory
    SharedRory over 2 years
    You should mention you are the author of the crate
  • at54321
    at54321 over 2 years
    It's 2021 and things have changed a bit. You can now use: rustc -Zunpretty=expanded some.rs. See Enselic's answer for more details.