Subcommands:
run, r Run binaries
test, t Run tests
+ nextest Run tests with nextest (requires cargo-nextest installed)
setup Only perform automatic setup, but without asking questions (for getting a proper libstd)
The cargo options are exactly the same as for `cargo run` and `cargo test`, respectively.
};
let subcommand = match &*subcommand {
"setup" => MiriCommand::Setup,
- "test" | "t" | "run" | "r" => MiriCommand::Forward(subcommand),
- // Invalid command.
+ "test" | "t" | "run" | "r" | "nextest" => MiriCommand::Forward(subcommand),
_ =>
show_error(format!(
- "`cargo miri` supports the following subcommands: `run`, `test`, and `setup`."
+ "`cargo miri` supports the following subcommands: `run`, `test`, `nextest`, and `setup`."
)),
};
let verbose = num_arg_flag("-v");
);
}
cmd.env("RUSTC_WRAPPER", &cargo_miri_path);
- // Having both `RUSTC_WRAPPER` and `RUSTC` set does some odd things, so let's avoid that.
- // See <https://github.com/rust-lang/miri/issues/2238>.
+ // We are going to invoke `MIRI` for everything, not `RUSTC`.
if env::var_os("RUSTC").is_some() && env::var_os("MIRI").is_none() {
println!(
"WARNING: Ignoring `RUSTC` environment variable; set `MIRI` if you want to control the binary used as the driver."
);
}
- cmd.env_remove("RUSTC");
+ // We'd prefer to just clear this env var, but cargo does not always honor `RUSTC_WRAPPER`
+ // (https://github.com/rust-lang/cargo/issues/10885). There is no good way to single out these invocations;
+ // some build scripts use the RUSTC env var as well. So we set it directly to the `miri` driver and
+ // hope that all they do is ask for the version number -- things could quickly go downhill from here.
+ // In `main`, we need the value of `RUSTC` to distinguish RUSTC_WRAPPER invocations from rustdoc
+ // or TARGET_RUNNER invocations, so we canonicalize it here to make it exceedingly unlikely that
+ // there would be a collision.
+ cmd.env("RUSTC", &fs::canonicalize(find_miri()).unwrap());
let runner_env_name =
|triple: &str| format!("CARGO_TARGET_{}_RUNNER", triple.to_uppercase().replace('-', "_"));
if verbose > 0 {
eprintln!(
- "[cargo-miri rustc] captured input:\n{}",
+ "[cargo-miri rustc inside rustdoc] captured input:\n{}",
std::str::from_utf8(&env.stdin).unwrap()
);
- eprintln!("[cargo-miri rustc] {:?}", cmd);
+ eprintln!("[cargo-miri rustc inside rustdoc] going to run:\n{:?}", cmd);
}
exec_with_pipe(cmd, &env.stdin);
// Run it.
if verbose > 0 {
- eprint!("[cargo-miri rustc] ");
+ eprintln!(
+ "[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate} print={print}"
+ );
+ eprintln!("[cargo-miri rustc] going to run:");
if verbose > 1 {
for (key, value) in env_vars_from_cmd(&cmd) {
eprintln!("{key}={value:?} \\");
match args.next().as_deref() {
Some("miri") => phase_cargo_miri(args),
- Some("rustc") => phase_rustc(args, RustcPhase::Build),
Some(arg) => {
+ // If the first arg is equal to the RUSTC variable (which should be set at this point),
+ // then we need to behave as rustc. This is the somewhat counter-intuitive behavior of
+ // having both RUSTC and RUSTC_WRAPPER set (see
+ // https://github.com/rust-lang/cargo/issues/10886).
+ if arg == env::var_os("RUSTC").unwrap() {
+ return phase_rustc(args, RustcPhase::Build);
+ }
// We have to distinguish the "runner" and "rustdoc" cases.
// As runner, the first argument is the binary (a file that should exist, with an absolute path);
// as rustdoc, the first argument is a flag (`--something`).