Skip to content

Commit

Permalink
Rollup merge of rust-lang#123260 - RalfJung:miri, r=RalfJung
Browse files Browse the repository at this point in the history
Miri subtree update

r? `@ghost`
  • Loading branch information
matthiaskrgr authored Mar 31, 2024
2 parents f04d068 + d5de305 commit 9abf4bc
Show file tree
Hide file tree
Showing 21 changed files with 214 additions and 186 deletions.
1 change: 1 addition & 0 deletions src/tools/miri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ harness = false
[features]
default = ["stack-cache"]
stack-cache = []
stack-cache-consistency-check = ["stack-cache"]

# Be aware that this file is inside a workspace when used via the
# submodule in the rustc repo. That means there are many cargo features
Expand Down
78 changes: 38 additions & 40 deletions src/tools/miri/cargo-miri/src/phases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,27 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
);
}
cmd.env("RUSTC_WRAPPER", &cargo_miri_path);
// There's also RUSTC_WORKSPACE_WRAPPER, which gets in the way of our own wrapping.
if env::var_os("RUSTC_WORKSPACE_WRAPPER").is_some() {
println!(
"WARNING: Ignoring `RUSTC_WORKSPACE_WRAPPER` environment variable, Miri does not support wrapping."
);
}
cmd.env_remove("RUSTC_WORKSPACE_WRAPPER");
// 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."
);
}
// Build scripts (and also cargo: https://github.com/rust-lang/cargo/issues/10885) will invoke
// `rustc` even when `RUSTC_WRAPPER` is set. To make sure everything is coherent, we want that
// to be the Miri driver, but acting as rustc, on the target level. (Target, rather than host,
// is needed for cross-interpretation situations.) This is not a perfect emulation of real rustc
// (it might be unable to produce binaries since the sysroot is check-only), but it's as close
// as we can get, and it's good enough for autocfg.
// Ideally we would set RUSTC to some non-existent path, so we can be sure our wrapping is
// always applied. However, buggy build scripts (https://github.com/eyre-rs/eyre/issues/84) and
// also cargo (https://github.com/rust-lang/cargo/issues/10885) will invoke `rustc` even when
// `RUSTC_WRAPPER` is set, bypassing the wrapper. To make sure everything is coherent, we want
// that to be the Miri driver, but acting as rustc, on the target level. (Target, rather than
// host, is needed for cross-interpretation situations.) This is not a perfect emulation of real
// rustc (it might be unable to produce binaries since the sysroot is check-only), but it's as
// close as we can get, and it's good enough for autocfg.
//
// 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
Expand Down Expand Up @@ -247,6 +256,16 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
/// Cargo does not give us this information directly, so we need to check
/// various command-line flags.
fn is_runnable_crate() -> bool {
// Determine whether this is cargo invoking rustc to get some infos. Ideally we'd check "is
// there a filename passed to rustc", but that's very hard as we would have to know whether
// e.g. `--print foo` is a booolean flag `--print` followed by filename `foo` or equivalent
// to `--print=foo`. So instead we use this more fragile approach of detecting the presence
// of a "query" flag rather than the absence of a filename.
let info_query = get_arg_flag_value("--print").is_some() || has_arg_flag("-vV");
if info_query {
// Nothing to run.
return false;
}
let is_bin = get_arg_flag_value("--crate-type").as_deref().unwrap_or("bin") == "bin";
let is_test = has_arg_flag("--test");
is_bin || is_test
Expand Down Expand Up @@ -285,16 +304,9 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
}
}

// phase_cargo_miri set `MIRI_BE_RUSTC` for when build scripts directly invoke the driver;
// however, if we get called back by cargo here, we'll carefully compute the right flags
// ourselves, so we first un-do what the earlier phase did.
env::remove_var("MIRI_BE_RUSTC");

let verbose = std::env::var("MIRI_VERBOSE")
.map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));
let target_crate = is_target_crate();
// Determine whether this is cargo invoking rustc to get some infos.
let info_query = get_arg_flag_value("--print").is_some() || has_arg_flag("-vV");

let store_json = |info: CrateRunInfo| {
if get_arg_flag_value("--emit").unwrap_or_default().split(',').any(|e| e == "dep-info") {
Expand All @@ -321,7 +333,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
}
};

let runnable_crate = !info_query && is_runnable_crate();
let runnable_crate = is_runnable_crate();

if runnable_crate && target_crate {
assert!(
Expand Down Expand Up @@ -395,7 +407,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
let mut emit_link_hack = false;
// Arguments are treated very differently depending on whether this crate is
// for interpretation by Miri, or for use by a build script / proc macro.
if !info_query && target_crate {
if target_crate {
// Forward arguments, but remove "link" from "--emit" to make this a check-only build.
let emit_flag = "--emit";
while let Some(arg) = args.next() {
Expand Down Expand Up @@ -429,17 +441,14 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
cmd.arg("-C").arg("panic=abort");
}
} else {
// For host crates (but not when we are just printing some info),
// we might still have to set the sysroot.
if !info_query {
// When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly
// due to bootstrap complications.
if let Some(sysroot) = std::env::var_os("MIRI_HOST_SYSROOT") {
cmd.arg("--sysroot").arg(sysroot);
}
// This is a host crate.
// When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly
// due to bootstrap complications.
if let Some(sysroot) = std::env::var_os("MIRI_HOST_SYSROOT") {
cmd.arg("--sysroot").arg(sysroot);
}

// For host crates or when we are printing, just forward everything.
// Forward everything.
cmd.args(args);
}

Expand All @@ -451,9 +460,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {

// Run it.
if verbose > 0 {
eprintln!(
"[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate} info_query={info_query}"
);
eprintln!("[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate}");
}

// Create a stub .rlib file if "link" was requested by cargo.
Expand All @@ -480,11 +487,6 @@ pub enum RunnerPhase {
}

pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: RunnerPhase) {
// phase_cargo_miri set `MIRI_BE_RUSTC` for when build scripts directly invoke the driver;
// however, if we get called back by cargo here, we'll carefully compute the right flags
// ourselves, so we first un-do what the earlier phase did.
env::remove_var("MIRI_BE_RUSTC");

let verbose = std::env::var("MIRI_VERBOSE")
.map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer"));

Expand Down Expand Up @@ -542,15 +544,13 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
// but when we run here, cargo does not interpret the JSON any more. `--json`
// then also needs to be dropped.
let mut args = info.args.into_iter();
let error_format_flag = "--error-format";
let json_flag = "--json";
while let Some(arg) = args.next() {
if arg == "--extern" {
forward_patched_extern_arg(&mut args, &mut cmd);
} else if let Some(suffix) = arg.strip_prefix(error_format_flag) {
} else if let Some(suffix) = arg.strip_prefix("--error-format") {
assert!(suffix.starts_with('='));
// Drop this argument.
} else if let Some(suffix) = arg.strip_prefix(json_flag) {
} else if let Some(suffix) = arg.strip_prefix("--json") {
assert!(suffix.starts_with('='));
// Drop this argument.
} else {
Expand Down Expand Up @@ -589,13 +589,11 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
let rustdoc = env::var("MIRI_ORIG_RUSTDOC").unwrap_or("rustdoc".to_string());
let mut cmd = Command::new(rustdoc);

let extern_flag = "--extern";
let runtool_flag = "--runtool";
while let Some(arg) = args.next() {
if arg == extern_flag {
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 == runtool_flag {
} else if arg == "--runtool" {
// An existing --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.
Expand Down
7 changes: 6 additions & 1 deletion src/tools/miri/cargo-miri/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ pub fn find_miri() -> PathBuf {
}

pub fn miri() -> Command {
Command::new(find_miri())
let mut cmd = Command::new(find_miri());
// We never want to inherit this from the environment.
// However, this is sometimes set in the environment to work around build scripts that don't
// honor RUSTC_WRAPPER. So remove it again in case it is set.
cmd.env_remove("MIRI_BE_RUSTC");
cmd
}

pub fn miri_for_host() -> Command {
Expand Down
25 changes: 16 additions & 9 deletions src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@ if [ "$HOST_TARGET" = i686-pc-windows-msvc ]; then
BASH="C:/Program Files/Git/usr/bin/bash"
fi

# Determine configuration for installed build
echo "Installing release version of Miri"
# Global configuration
export RUSTFLAGS="-D warnings"
export CARGO_INCREMENTAL=0
export CARGO_EXTRA_FLAGS="--locked"

# Determine configuration for installed build
echo "Installing release version of Miri"
./miri install

# Prepare debug build for direct `./miri` invocations
echo "Building debug version of Miri"
echo "Checking various feature flag configurations"
./miri check --no-default-features # make sure this can be built
./miri check --all-features # and this, too
./miri check # and this, too
# `--all-features` is used for the build below, so no extra check needed.

# Prepare debug build for direct `./miri` invocations.
# We enable all features to make sure the Stacked Borrows consistency check runs.
echo "Building debug version of Miri"
export CARGO_EXTRA_FLAGS="$CARGO_EXTRA_FLAGS --all-features"
./miri build --all-targets # the build that all the `./miri test` below will use

endgroup
Expand All @@ -46,8 +53,8 @@ function run_tests {
fi

## ui test suite
# On the host and on Linux, also stress-test the GC.
if [ -z "${MIRI_TEST_TARGET:-}" ] || [ "$HOST_TARGET" = x86_64-unknown-linux-gnu ]; then
# On the host, also stress-test the GC.
if [ -z "${MIRI_TEST_TARGET:-}" ]; then
MIRIFLAGS="${MIRIFLAGS:-} -Zmiri-provenance-gc=1" ./miri test
else
./miri test
Expand Down Expand Up @@ -130,6 +137,8 @@ case $HOST_TARGET in
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
# Some targets are only partially supported.
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus
MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple pthread-threadname libc-getentropy libc-getrandom libc-misc libc-fs atomic env align num_cpus
Expand All @@ -145,9 +154,7 @@ case $HOST_TARGET in
MIRI_TEST_TARGET=x86_64-pc-windows-msvc run_tests
;;
i686-pc-windows-msvc)
MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
;;
*)
echo "FATAL: unknown OS"
Expand Down
23 changes: 13 additions & 10 deletions src/tools/miri/miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,10 +479,11 @@ impl Command {
Ok(())
}

fn run(dep: bool, flags: Vec<OsString>) -> Result<()> {
fn run(dep: bool, mut flags: Vec<OsString>) -> Result<()> {
let mut e = MiriEnv::new()?;
// Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so
// that we set the MIRI_SYSROOT up the right way.
// that we set the MIRI_SYSROOT up the right way. We must make sure that
// MIRI_TEST_TARGET and `--target` are in sync.
use itertools::Itertools;
let target = flags
.iter()
Expand All @@ -493,33 +494,35 @@ impl Command {
// Found it!
e.sh.set_var("MIRI_TEST_TARGET", target);
} else if let Ok(target) = std::env::var("MIRI_TEST_TARGET") {
// Make sure miri actually uses this target.
let miriflags = e.sh.var("MIRIFLAGS").unwrap_or_default();
e.sh.set_var("MIRIFLAGS", format!("{miriflags} --target {target}"));
// Convert `MIRI_TEST_TARGET` into `--target`.
flags.push("--target".into());
flags.push(target.into());
}
// Scan for "--edition" (we'll set one ourselves if that flag is not present).
// Scan for "--edition", set one ourselves if that flag is not present.
let have_edition =
flags.iter().take_while(|arg| *arg != "--").any(|arg| *arg == "--edition");
if !have_edition {
flags.push("--edition=2021".into()); // keep in sync with `tests/ui.rs`.`
}

// Prepare a sysroot.
e.build_miri_sysroot(/* quiet */ true)?;

// Then run the actual command.
// Then run the actual command. Also add MIRIFLAGS.
let miri_manifest = path!(e.miri_dir / "Cargo.toml");
let miri_flags = e.sh.var("MIRIFLAGS").unwrap_or_default();
let miri_flags = flagsplit(&miri_flags);
let toolchain = &e.toolchain;
let extra_flags = &e.cargo_extra_flags;
let edition_flags = (!have_edition).then_some("--edition=2021"); // keep in sync with `tests/ui.rs`.`
if dep {
cmd!(
e.sh,
"cargo +{toolchain} --quiet test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {edition_flags...} {flags...}"
"cargo +{toolchain} --quiet test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {flags...}"
).quiet().run()?;
} else {
cmd!(
e.sh,
"cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {edition_flags...} {flags...}"
"cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {flags...}"
).quiet().run()?;
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cb7c63606e53715f94f3ba04d38e50772e4cd23d
5baf1e13f568b61e121953bf6a3d09faee7dd446
10 changes: 5 additions & 5 deletions src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl<'tcx> Stack {
/// Panics if any of the caching mechanisms have broken,
/// - The StackCache indices don't refer to the parallel items,
/// - There are no Unique items outside of first_unique..last_unique
#[cfg(all(feature = "stack-cache", debug_assertions))]
#[cfg(feature = "stack-cache-consistency-check")]
fn verify_cache_consistency(&self) {
// Only a full cache needs to be valid. Also see the comments in find_granting_cache
// and set_unknown_bottom.
Expand Down Expand Up @@ -190,7 +190,7 @@ impl<'tcx> Stack {
tag: ProvenanceExtra,
exposed_tags: &FxHashSet<BorTag>,
) -> Result<Option<usize>, ()> {
#[cfg(all(feature = "stack-cache", debug_assertions))]
#[cfg(feature = "stack-cache-consistency-check")]
self.verify_cache_consistency();

let ProvenanceExtra::Concrete(tag) = tag else {
Expand Down Expand Up @@ -327,7 +327,7 @@ impl<'tcx> Stack {
// This primes the cache for the next access, which is almost always the just-added tag.
self.cache.add(new_idx, new);

#[cfg(debug_assertions)]
#[cfg(feature = "stack-cache-consistency-check")]
self.verify_cache_consistency();
}

Expand Down Expand Up @@ -410,7 +410,7 @@ impl<'tcx> Stack {
self.unique_range.end = self.unique_range.end.min(disable_start);
}

#[cfg(all(feature = "stack-cache", debug_assertions))]
#[cfg(feature = "stack-cache-consistency-check")]
self.verify_cache_consistency();

Ok(())
Expand Down Expand Up @@ -465,7 +465,7 @@ impl<'tcx> Stack {
self.unique_range = 0..0;
}

#[cfg(all(feature = "stack-cache", debug_assertions))]
#[cfg(feature = "stack-cache-consistency-check")]
self.verify_cache_consistency();
Ok(())
}
Expand Down
8 changes: 4 additions & 4 deletions src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ type S = &'static str;
/// Pretty-printing details
///
/// Example:
/// ```
/// ```rust,ignore (private type)
/// DisplayFmtWrapper {
/// top: '>',
/// bot: '<',
Expand Down Expand Up @@ -393,7 +393,7 @@ struct DisplayFmtWrapper {
/// Formating of the permissions on each range.
///
/// Example:
/// ```
/// ```rust,ignore (private type)
/// DisplayFmtPermission {
/// open: "[",
/// sep: "|",
Expand Down Expand Up @@ -425,7 +425,7 @@ struct DisplayFmtPermission {
/// Formating of the tree structure.
///
/// Example:
/// ```
/// ```rust,ignore (private type)
/// DisplayFmtPadding {
/// join_middle: "|-",
/// join_last: "'-",
Expand Down Expand Up @@ -463,7 +463,7 @@ struct DisplayFmtPadding {
/// How to show whether a location has been accessed
///
/// Example:
/// ```
/// ```rust,ignore (private type)
/// DisplayFmtAccess {
/// yes: " ",
/// no: "?",
Expand Down
Loading

0 comments on commit 9abf4bc

Please sign in to comment.