Skip to content

Rustup #4324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 17, 2025
Merged

Rustup #4324

34 changes: 22 additions & 12 deletions cargo-miri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,37 @@ fn main() {
return;
}

let Some(first) = args.next() else {
show_error!(
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
)
};

// The way rustdoc invokes rustc is indistinguishable from the way cargo invokes rustdoc by the
// arguments alone. `phase_cargo_rustdoc` sets this environment variable to let us disambiguate.
if env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some() {
// ...however, we then also see this variable when rustdoc invokes us as the testrunner!
// The runner is invoked as `$runtool ($runtool-arg)* output_file`;
// since we don't specify any runtool-args, and rustdoc supplies multiple arguments to
// the test-builder unconditionally, we can just check the number of remaining arguments:
if args.len() == 1 {
phase_runner(args, RunnerPhase::Rustdoc);
} else {
phase_rustc(args, RustcPhase::Rustdoc);
// In that case the first argument is `runner` and there are no more arguments.
match first.as_str() {
"runner" => phase_runner(args, RunnerPhase::Rustdoc),
flag if flag.starts_with("--") || flag.starts_with("@") => {
// This is probably rustdoc invoking us to build the test. But we need to get `first`
// "back onto the iterator", it is some part of the rustc invocation.
phase_rustc(iter::once(first).chain(args), RustcPhase::Rustdoc);
}
_ => {
show_error!(
"`cargo-miri` failed to recognize which phase of the build process this is, please report a bug.\n\
We are inside MIRI_CALLED_FROM_RUSTDOC.\n\
The command-line arguments were: {:#?}",
Vec::from_iter(env::args()),
);
}
}

return;
}

let Some(first) = args.next() else {
show_error!(
"`cargo-miri` called without first argument; please only invoke this binary through `cargo miri`"
)
};
match first.as_str() {
"miri" => phase_cargo_miri(args),
"runner" => phase_runner(args, RunnerPhase::Cargo),
Expand Down
9 changes: 2 additions & 7 deletions cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,11 +666,6 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
if arg == "--extern" {
// Patch --extern arguments to use *.rmeta files, since phase_cargo_rustc only creates stub *.rlib files.
forward_patched_extern_arg(&mut args, &mut cmd);
} else if arg == "--test-runtool" {
// An existing --test-runtool flag indicates cargo is running in cross-target mode, which we don't support.
// Note that this is only passed when cargo is run with the unstable -Zdoctest-xcompile flag;
// otherwise, we won't be called as rustdoc at all.
show_error!("cross-interpreting doctests is not currently supported by Miri.");
} else {
cmd.arg(arg);
}
Expand Down Expand Up @@ -702,10 +697,10 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
// make sure the 'miri' flag is set for rustdoc
cmd.arg("--cfg").arg("miri");

// Make rustdoc call us back.
// Make rustdoc call us back for the build.
// (cargo already sets `--test-runtool` to us since we are the cargo test runner.)
let cargo_miri_path = env::current_exe().expect("current executable path invalid");
cmd.arg("--test-builder").arg(&cargo_miri_path); // invoked by forwarding most arguments
cmd.arg("--test-runtool").arg(&cargo_miri_path); // invoked with just a single path argument

debug_cmd("[cargo-miri rustdoc]", verbose, &cmd);
exec(cmd)
Expand Down
8 changes: 3 additions & 5 deletions cargo-miri/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ pub fn setup(
let ask_user = !only_setup;
let print_sysroot = only_setup && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
let show_setup = only_setup && !print_sysroot;
if !only_setup {
if let Some(sysroot) = std::env::var_os("MIRI_SYSROOT") {
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
return sysroot.into();
}
if !only_setup && let Some(sysroot) = std::env::var_os("MIRI_SYSROOT") {
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
return sysroot.into();
}

// Determine where the rust sources are located. The env var trumps auto-detection.
Expand Down
14 changes: 5 additions & 9 deletions miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,11 +675,9 @@ impl Command {
let mut early_flags = Vec::<OsString>::new();

// In `dep` mode, the target is already passed via `MIRI_TEST_TARGET`
if !dep {
if let Some(target) = &target {
early_flags.push("--target".into());
early_flags.push(target.into());
}
if !dep && let Some(target) = &target {
early_flags.push("--target".into());
early_flags.push(target.into());
}
early_flags.push("--edition".into());
early_flags.push(edition.as_deref().unwrap_or("2021").into());
Expand Down Expand Up @@ -707,10 +705,8 @@ impl Command {
// Add Miri flags
let mut cmd = cmd.args(&miri_flags).args(&early_flags).args(&flags);
// For `--dep` we also need to set the target in the env var.
if dep {
if let Some(target) = &target {
cmd = cmd.env("MIRI_TEST_TARGET", target);
}
if dep && let Some(target) = &target {
cmd = cmd.env("MIRI_TEST_TARGET", target);
}
// Finally, run the thing.
Ok(cmd.run()?)
Expand Down
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
718ddf660e6a1802c39b4962cf7eaa4db57025ef
a69bc17fb8026bdc0d24bb1896ff95f0eba1da4e
1 change: 1 addition & 0 deletions src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Now we make a function call, and pass `data` as first and only argument.
let f_instance = this.get_ptr_fn(try_fn)?.as_instance()?;
trace!("try_fn: {:?}", f_instance);
#[allow(clippy::cloned_ref_to_slice_refs)] // the code is clearer as-is
this.call_function(
f_instance,
ExternAbi::Rust,
Expand Down
17 changes: 6 additions & 11 deletions test-cargo-miri/run-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,19 @@ def test_cargo_miri_run():
)

def test_cargo_miri_test():
# rustdoc is not run on foreign targets
is_foreign = ARGS.target is not None
default_ref = "test.cross-target.stdout.ref" if is_foreign else "test.default.stdout.ref"
filter_ref = "test.filter.cross-target.stdout.ref" if is_foreign else "test.filter.stdout.ref"

test("`cargo miri test`",
cargo_miri("test"),
default_ref, "test.empty.ref",
"test.default.stdout.ref", "test.empty.ref",
env={'MIRIFLAGS': "-Zmiri-seed=4242"},
)
test("`cargo miri test` (no isolation, no doctests)",
cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml`
"test.cross-target.stdout.ref", "test.empty.ref",
"test.no-doc.stdout.ref", "test.empty.ref",
env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
)
test("`cargo miri test` (with filter)",
cargo_miri("test") + ["--", "--format=pretty", "pl"],
filter_ref, "test.empty.ref",
"test.filter.stdout.ref", "test.empty.ref",
)
test("`cargo miri test` (test target)",
cargo_miri("test") + ["--test", "test", "--", "--format=pretty"],
Expand All @@ -171,7 +166,7 @@ def test_cargo_miri_test():
)
test("`cargo miri t` (subcrate, no isolation)",
cargo_miri("t") + ["-p", "subcrate"],
"test.subcrate.cross-target.stdout.ref" if is_foreign else "test.subcrate.stdout.ref",
"test.subcrate.stdout.ref",
"test.empty.ref",
env={'MIRIFLAGS': "-Zmiri-disable-isolation"},
)
Expand All @@ -181,12 +176,12 @@ def test_cargo_miri_test():
)
test("`cargo miri test` (custom target dir)",
cargo_miri("test") + ["--target-dir=custom-test"],
default_ref, "test.empty.ref",
"test.default.stdout.ref", "test.empty.ref",
)
del os.environ["CARGO_TARGET_DIR"] # this overrides `build.target-dir` passed by `--config`, so unset it
test("`cargo miri test` (config-cli)",
cargo_miri("test") + ["--config=build.target-dir=\"config-cli\""],
default_ref, "test.empty.ref",
"test.default.stdout.ref", "test.empty.ref",
)
if ARGS.multi_target:
test_cargo_miri_multi_target()
Expand Down
12 changes: 0 additions & 12 deletions test-cargo-miri/test.filter.cross-target.stdout.ref

This file was deleted.

10 changes: 10 additions & 0 deletions test-cargo-miri/test.multiple_targets.stdout.ref
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ running 6 tests
...i..
test result: ok. 5 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME


running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME


running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

11 changes: 0 additions & 11 deletions test-cargo-miri/test.subcrate.cross-target.stdout.ref

This file was deleted.

8 changes: 4 additions & 4 deletions tests/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,10 @@ fn main() -> Result<()> {
let mut args = std::env::args_os();

// Skip the program name and check whether this is a `./miri run-dep` invocation
if let Some(first) = args.nth(1) {
if first == "--miri-run-dep-mode" {
return run_dep_mode(target, args);
}
if let Some(first) = args.nth(1)
&& first == "--miri-run-dep-mode"
{
return run_dep_mode(target, args);
}

ui(Mode::Pass, "tests/pass", &target, WithoutDependencies, tmpdir.path())?;
Expand Down