cargo rustc 宏展开

RUSTC_BOOTSTRAP=1

如果需要在稳定版编译器上执行一些夜间发布功能,可以设置该环境变量。

$ cargo rustc -- -Zunpretty=expanded
   Compiling xxx v0.1.0 (F:\xxx)
error: the option `Z` is only accepted on the nightly compiler


$ RUSTC_BOOTSTRAP=1 cargo rustc -- -Z unpretty=expanded
   Compiling xxx v0.1.0 (F:\xxx)
#![feature(prelude_import)]
#![windows_subsystem = "console"]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;

宏展开

https://stackoverflow.com/questions/28580386/how-do-i-see-the-expanded-macro-code-thats-causing-my-compile-error

这会打印整个工程展开后的代码:

RUSTC_BOOTSTRAP=1 cargo rustc -- -Z unpretty=expanded

作为一个例子,我们想研究以下代码:

async fn config(method: Method, config: extract::State<std::sync::Arc<Mutex<Config>>>, payload: Option<Json<Config>>) -> impl IntoResponse {
    match method {
        Method::GET => {
            let config = config.lock().await;

            //let config: Config = *config; // MutexGuard持有的Config对象没有实现Copy,不能移动该值,只能借用,
            //Ok((StatusCode::OK, Json(config))) // 当然了,我们不知道,所以很好奇为什么这样不行,最后试出下面的代码

            Ok((StatusCode::OK, Json(serde_json::json!(*config)))) // 这里不会移动config的生命周期,代码可以运行
        }
        _ => Err((StatusCode::METHOD_NOT_ALLOWED, "Only allow GET and POST requests"))
    }
}

我们展开后发现:

Method::GET => {
    let config = config.lock().await;
    Ok((StatusCode::OK,
            Json(::serde_json::to_value(&*config).unwrap())))
}

现在我们知道了:

let config: &Config = &*config; // 这样是可行的,但是
Ok((StatusCode::OK, Json(config))) // 引用不行
Ok((StatusCode::OK, Json(config.clone()))) // 克隆勉强可行

所以还是用Json<Value>吧!

安装cargo-expand

为了方便展开代码,同时可以着色、格式化输出,可以安装该工具:

cargo install cargo-expand

使用方法:

RUSTC_BOOTSTRAP=1 cargo expand
RUSTC_BOOTSTRAP=1 cargo expand --example xxx

打印cfg

使用 rustc --print cfg 可以知道当前平台的所有 cfg 条件,当然,我们通过cargo调用最好不过。

$ cargo rustc -- --print cfg
   Compiling xxx v0.1.0 (F:\xxx)
debug_assertions
panic="unwind"
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows

看看 release 编译时的 cfg 吧:

$ cargo rustc --release -- --print cfg
panic="unwind"
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows

自定义cfg:

RUSTFLAGS="--cfg debug" cargo run

或者写入.cargo/config[.toml]:

[build]
rustflags = ["--cfg", "debug"]     # custom flags for `rustc`
posted @ 2023-04-18 10:45  develon  阅读(304)  评论(1编辑  收藏  举报