Skip to content

Commit 3dff1d4

Browse files
author
hyd-dev
committed
Don't use MIRI_DEFAULT_ARGS to compile host crates
1 parent 7b2e325 commit 3dff1d4

File tree

11 files changed

+84
-16
lines changed

11 files changed

+84
-16
lines changed

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ You can pass arguments to Miri via `MIRIFLAGS`. For example,
100100
`MIRIFLAGS="-Zmiri-disable-stacked-borrows" cargo miri run` runs the program
101101
without checking the aliasing of references.
102102

103-
When compiling code via `cargo miri`, the `cfg(miri)` config flag is set. You
104-
can use this to ignore test cases that fail under Miri because they do things
105-
Miri does not support:
103+
When compiling code via `cargo miri`, the `cfg(miri)` config flag is set for code
104+
that will be interpret under Miri. You can use this to ignore test cases that fail
105+
under Miri because they do things Miri does not support:
106106

107107
```rust
108108
#[test]
@@ -286,9 +286,11 @@ Moreover, Miri recognizes some environment variables:
286286
The following environment variables are internal, but used to communicate between
287287
different Miri binaries, and as such worth documenting:
288288

289-
* `MIRI_BE_RUSTC` when set to any value tells the Miri driver to actually not
290-
interpret the code but compile it like rustc would. This is useful to be sure
291-
that the compiled `rlib`s are compatible with Miri.
289+
* `MIRI_BE_RUSTC` can be set to `host` or `target`. It tells the Miri driver to
290+
actually not interpret the code but compile it like rustc would. With `target`, Miri sets
291+
some compiler flags to prepare the code for interpretation; with `host`, this is not done.
292+
This environment variable is useful to be sure that the compiled `rlib`s are compatible
293+
with Miri.
292294
When set while running `cargo-miri`, it indicates that we are part of a sysroot
293295
build (for which some crates need special treatment).
294296
* `MIRI_CALLED_FROM_RUSTDOC` when set to any value tells `cargo-miri` that it is

cargo-miri/bin.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ path = "lib.rs"
420420
} else {
421421
command.env("RUSTC", &cargo_miri_path);
422422
}
423-
command.env("MIRI_BE_RUSTC", "1");
423+
command.env("MIRI_BE_RUSTC", "target");
424424
// Make sure there are no other wrappers or flags getting in our way
425425
// (Cc https://github.com/rust-lang/miri/issues/1421).
426426
// This is consistent with normal `cargo build` that does not apply `RUSTFLAGS`
@@ -694,7 +694,7 @@ fn phase_cargo_rustc(mut args: env::Args) {
694694
}
695695

696696
cmd.args(&env.args);
697-
cmd.env("MIRI_BE_RUSTC", "1");
697+
cmd.env("MIRI_BE_RUSTC", "target");
698698

699699
if verbose {
700700
eprintln!("[cargo-miri rustc] captured input:\n{}", std::str::from_utf8(&env.stdin).unwrap());
@@ -758,7 +758,9 @@ fn phase_cargo_rustc(mut args: env::Args) {
758758

759759
// We want to compile, not interpret. We still use Miri to make sure the compiler version etc
760760
// are the exact same as what is used for interpretation.
761-
cmd.env("MIRI_BE_RUSTC", "1");
761+
// MIRI_DEFAULT_ARGS should not be used to build host crates, hence setting "target" or "host"
762+
// as the value here to help Miri differentiate them.
763+
cmd.env("MIRI_BE_RUSTC", if target_crate { "target" } else { "host" });
762764

763765
// Run it.
764766
if verbose {

src/bin/miri.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ fn compile_time_sysroot() -> Option<String> {
135135
}
136136

137137
/// Execute a compiler with the given CLI arguments and callbacks.
138-
fn run_compiler(mut args: Vec<String>, callbacks: &mut (dyn rustc_driver::Callbacks + Send)) -> ! {
138+
fn run_compiler(
139+
mut args: Vec<String>,
140+
callbacks: &mut (dyn rustc_driver::Callbacks + Send),
141+
insert_default_args: bool,
142+
) -> ! {
139143
// Make sure we use the right default sysroot. The default sysroot is wrong,
140144
// because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
141145
//
@@ -151,9 +155,11 @@ fn run_compiler(mut args: Vec<String>, callbacks: &mut (dyn rustc_driver::Callba
151155
}
152156
}
153157

154-
// Some options have different defaults in Miri than in plain rustc; apply those by making
155-
// them the first arguments after the binary name (but later arguments can overwrite them).
156-
args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string));
158+
if insert_default_args {
159+
// Some options have different defaults in Miri than in plain rustc; apply those by making
160+
// them the first arguments after the binary name (but later arguments can overwrite them).
161+
args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string));
162+
}
157163

158164
// Invoke compiler, and handle return code.
159165
let exit_code = rustc_driver::catch_with_exit_code(move || {
@@ -166,11 +172,24 @@ fn main() {
166172
rustc_driver::install_ice_hook();
167173

168174
// If the environment asks us to actually be rustc, then do that.
169-
if env::var_os("MIRI_BE_RUSTC").is_some() {
175+
if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
170176
rustc_driver::init_rustc_env_logger();
177+
178+
// Don't insert `MIRI_DEFAULT_ARGS`, in particular, `--cfg=miri`, if we are building a
179+
// "host" crate. That may cause procedural macros (and probably build scripts) to depend
180+
// on Miri-only symbols, such as `miri_resolve_frame`:
181+
// https://github.com/rust-lang/miri/issues/1760
182+
let insert_default_args = if crate_kind == "target" {
183+
true
184+
} else if crate_kind == "host" {
185+
false
186+
} else {
187+
panic!("invalid `MIRI_BE_RUSTC` value: {:?}", crate_kind)
188+
};
189+
171190
// We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
172191
let mut callbacks = rustc_driver::TimePassesCallbacks::default();
173-
run_compiler(env::args().collect(), &mut callbacks)
192+
run_compiler(env::args().collect(), &mut callbacks, insert_default_args)
174193
}
175194

176195
// Init loggers the Miri way.
@@ -300,5 +319,5 @@ fn main() {
300319

301320
debug!("rustc arguments: {:?}", rustc_args);
302321
debug!("crate arguments: {:?}", miri_config.args);
303-
run_compiler(rustc_args, &mut MiriCompilerCalls { miri_config })
322+
run_compiler(rustc_args, &mut MiriCompilerCalls { miri_config }, /* insert_default_args: */ true)
304323
}

test-cargo-miri/Cargo.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test-cargo-miri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ cdylib = { path = "cdylib" }
1313
issue_1567 = { path = "issue-1567" }
1414
issue_1691 = { path = "issue-1691" }
1515
issue_1705 = { path = "issue-1705" }
16+
issue_1760 = { path = "issue-1760" }
1617

1718
[dev-dependencies]
1819
rand = { version = "0.8", features = ["small_rng"] }

test-cargo-miri/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#![feature(llvm_asm)]
22

3+
use std::env;
4+
5+
#[cfg(miri)]
6+
compile_error!("`miri` cfg should not be set in build script");
7+
38
fn not_in_miri() -> i32 {
49
// Inline assembly definitely does not work in Miri.
510
let dummy = 42;
@@ -11,6 +16,9 @@ fn not_in_miri() -> i32 {
1116

1217
fn main() {
1318
not_in_miri();
19+
// Cargo calls `miri --print=cfg` to populate the `CARGO_CFG_*` env vars.
20+
// Make sure that the "miri" flag is set.
21+
assert!(env::var_os("CARGO_CFG_MIRI").is_some());
1422
println!("cargo:rerun-if-changed=build.rs");
1523
println!("cargo:rerun-if-env-changed=MIRITESTVAR");
1624
println!("cargo:rustc-env=MIRITESTVAR=testval");

test-cargo-miri/issue-1760/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "issue_1760"
3+
version = "0.1.0"
4+
authors = ["Miri Team"]
5+
edition = "2018"
6+
7+
[lib]
8+
proc-macro = true

test-cargo-miri/issue-1760/build.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use std::env;
2+
3+
#[cfg(miri)]
4+
compile_error!("`miri` cfg should not be set in build script");
5+
6+
fn main() {
7+
// Cargo calls `miri --print=cfg` to populate the `CARGO_CFG_*` env vars.
8+
// Make sure that the "miri" flag is not set since we are building a procedural macro crate.
9+
assert!(env::var_os("CARGO_CFG_MIRI").is_none());
10+
}

test-cargo-miri/issue-1760/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use proc_macro::TokenStream;
2+
3+
#[cfg(miri)]
4+
compile_error!("`miri` cfg should not be set in proc-macro");
5+
6+
#[proc_macro]
7+
pub fn use_the_dependency(_: TokenStream) -> TokenStream {
8+
TokenStream::new()
9+
}

test-cargo-miri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
pub fn make_true() -> bool {
1212
issue_1567::use_the_dependency();
1313
issue_1705::use_the_dependency();
14+
issue_1760::use_the_dependency!();
1415
issue_1691::use_me()
1516
}

0 commit comments

Comments
 (0)