web-dev-qa-db-fra.com

Comment puis-je voir le code de macro étendu à l'origine de mon erreur de compilation?

J'ai une erreur de compilation impliquant une 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

Malheureusement, la macro est récursive, il est donc difficile de comprendre de quoi le compilateur se plaint, et il semble que les numéros de ligne correspondent à la macro développée plutôt qu'à mon code.

Comment puis-je voir la macro développée? Y a-t-il un drapeau que je peux passer à rustc (ou mieux encore, à cargo) pour le vider?

(Cette macro provient de Rust-mdo , bien que je ne pense pas que cela soit important.)

40
Caspar

Une alternative plus concise à cargo rustc -- -Zunstable-options --pretty=expanded est la caisse cargo-expand . Il fournit une sous-commande Cargo cargo expand qui imprime le résultat de l'expansion des macros. Il passe également le code développé via rustfmt , ce qui donne généralement un code beaucoup plus lisible que la sortie par défaut de rustc.

Installez en exécutant cargo install cargo-expand.

49
dtolnay

Oui, vous pouvez passer un indicateur spécial à rustc, appelé --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 ()
                                                                          {
                                                                          ()
                                                                          =>
                                                                          [],
                                                                      }));
}

Cependant, vous devez d'abord l'autoriser en passant -Z unstable-options.

Depuis Rust 1.1 vous pouvez passer ces arguments à Cargo, comme ceci:

cargo rustc -- -Z unstable-options --pretty=expanded
46
Vladimir Matveev