From 9dba78a76b7343ac70321b4224746f5e412df088 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 19 Jul 2022 13:19:00 -0400 Subject: [PATCH] show a better error when running Miri with the wrong sysroot --- cargo-miri/bin.rs | 15 +++++++++------ src/bin/miri.rs | 32 +++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/cargo-miri/bin.rs b/cargo-miri/bin.rs index c4ed92d03852..233d81826eec 100644 --- a/cargo-miri/bin.rs +++ b/cargo-miri/bin.rs @@ -374,12 +374,15 @@ fn setup(subcommand: MiriCommand) { } None => { // Check for `rust-src` rustup component. - let sysroot = miri() - .args(&["--print", "sysroot"]) - .output() - .expect("failed to determine sysroot") - .stdout; - let sysroot = std::str::from_utf8(&sysroot).unwrap(); + let output = + miri().args(&["--print", "sysroot"]).output().expect("failed to determine sysroot"); + if !output.status.success() { + show_error(format!( + "Failed to determine sysroot; Miri said:\n{}", + String::from_utf8_lossy(&output.stderr).trim_end() + )); + } + let sysroot = std::str::from_utf8(&output.stdout).unwrap(); let sysroot = Path::new(sysroot.trim_end_matches('\n')); // Check for `$SYSROOT/lib/rustlib/src/rust/library`; test if that contains `std/Cargo.toml`. let rustup_src = diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 4f00e4be18ab..5131f3ae9ca9 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -1,5 +1,5 @@ #![feature(rustc_private, stmt_expr_attributes)] -#![allow(clippy::manual_range_contains)] +#![allow(clippy::manual_range_contains, clippy::useless_format)] extern crate rustc_data_structures; extern crate rustc_driver; @@ -143,6 +143,11 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { } } +fn show_error(msg: String) -> ! { + eprintln!("fatal error: {}", msg); + std::process::exit(1) +} + fn init_early_loggers() { // Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to // initialize them both, and we always initialize `miri`'s first. @@ -214,13 +219,26 @@ fn compile_time_sysroot() -> Option { let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); Some(match (home, toolchain) { - (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain), - _ => - option_env!("RUST_SYSROOT") - .expect( + (Some(home), Some(toolchain)) => { + // Check that at runtime, we are still in this toolchain. + let toolchain_runtime = + env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN")); + if !matches!(toolchain_runtime, Some(r) if r == toolchain) { + show_error(format!( + "This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\ + Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`." + )); + } + + format!("{}/toolchains/{}", home, toolchain) + } + _ => option_env!("RUST_SYSROOT") + .unwrap_or_else(|| { + show_error(format!( "To build Miri without rustup, set the `RUST_SYSROOT` env var at build time", - ) - .to_owned(), + )) + }) + .to_owned(), }) }