diff --git a/cargo-miri/src/phases.rs b/cargo-miri/src/phases.rs index 0716f4add9..0f04397b72 100644 --- a/cargo-miri/src/phases.rs +++ b/cargo-miri/src/phases.rs @@ -52,18 +52,6 @@ fn show_version() { println!(); } -fn forward_patched_extern_arg(args: &mut impl Iterator, cmd: &mut Command) { - cmd.arg("--extern"); // always forward flag, but adjust filename: - let path = args.next().expect("`--extern` should be followed by a filename"); - if let Some(lib) = path.strip_suffix(".rlib") { - // If this is an rlib, make it an rmeta. - cmd.arg(format!("{lib}.rmeta")); - } else { - // Some other extern file (e.g. a `.so`). Forward unchanged. - cmd.arg(path); - } -} - pub fn phase_cargo_miri(mut args: impl Iterator) { // Require a subcommand before any flags. // We cannot know which of those flags take arguments and which do not, @@ -276,7 +264,7 @@ pub enum RustcPhase { Rustdoc, } -pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { +pub fn phase_rustc(args: impl Iterator, phase: RustcPhase) { /// Determines if we are being invoked (as rustc) to build a crate for /// the "target" architecture, in contrast to the "host" architecture. /// Host crates are for build scripts and proc macros and still need to @@ -444,7 +432,6 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { } let mut cmd = miri(); - 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 target_crate { @@ -455,7 +442,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { } // Forward arguments, but patched. - let emit_flag = "--emit"; + // This hack helps bootstrap run standard library tests in Miri. The issue is as follows: // when running `cargo miri test` on libcore, cargo builds a local copy of core and makes it // a dependency of the integration test crate. This copy duplicates all the lang items, so @@ -471,30 +458,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some() && !runnable_crate && phase == RustcPhase::Build; - while let Some(arg) = args.next() { - // Patch `--emit`: remove "link" from "--emit" to make this a check-only build. - if let Some(val) = arg.strip_prefix(emit_flag) { - // Patch this argument. First, extract its value. - let val = - val.strip_prefix('=').expect("`cargo` should pass `--emit=X` as one argument"); - let mut val: Vec<_> = val.split(',').collect(); - // Now make sure "link" is not in there, but "metadata" is. - if let Some(i) = val.iter().position(|&s| s == "link") { - emit_link_hack = true; - val.remove(i); - if !val.contains(&"metadata") { - val.push("metadata"); - } - } - cmd.arg(format!("{emit_flag}={}", val.join(","))); - continue; - } - // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files: - // https://github.com/rust-lang/miri/issues/1705 - if arg == "--extern" { - forward_patched_extern_arg(&mut args, &mut cmd); - continue; - } + for arg in args { // If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a // `lib.miri.rs` file exists, then build that instead. if replace_librs { @@ -543,17 +507,6 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { eprintln!("[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate}"); } - // Create a stub .rlib file if "link" was requested by cargo. - // This is necessary to prevent cargo from doing rebuilds all the time. - if emit_link_hack { - for filename in out_filenames() { - if verbose > 0 { - eprintln!("[cargo-miri rustc] creating fake lib file at `{}`", filename.display()); - } - File::create(filename).expect("failed to create fake lib file"); - } - } - debug_cmd("[cargo-miri rustc]", verbose, &cmd); exec(cmd); } @@ -624,17 +577,11 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); } // Forward rustc arguments. - // We need to patch "--extern" filenames because we forced a check-only - // build without cargo knowing about that: replace `.rlib` suffix by - // `.rmeta`. - // We also need to remove `--error-format` as cargo specifies that to be JSON, + // We need to remove `--error-format` as cargo specifies that to be JSON, // 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.iter(); - while let Some(arg) = args.next() { - if arg == "--extern" { - forward_patched_extern_arg(&mut (&mut args).cloned(), &mut cmd); - } else if let Some(suffix) = arg.strip_prefix("--error-format") { + for arg in &info.args { + 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") { @@ -668,7 +615,7 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner } } -pub fn phase_rustdoc(mut args: impl Iterator) { +pub fn phase_rustdoc(args: impl Iterator) { let verbose = env::var("MIRI_VERBOSE") .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer")); @@ -676,15 +623,7 @@ pub fn phase_rustdoc(mut args: impl Iterator) { // of the old value into MIRI_ORIG_RUSTDOC. So that's what we have to invoke now. let rustdoc = env::var("MIRI_ORIG_RUSTDOC").unwrap_or("rustdoc".to_string()); let mut cmd = Command::new(rustdoc); - - while let Some(arg) = args.next() { - 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 { - cmd.arg(arg); - } - } + cmd.args(args); // Doctests of `proc-macro` crates (and their dependencies) are always built for the host, // so we are not able to run them in Miri. diff --git a/cargo-miri/src/setup.rs b/cargo-miri/src/setup.rs index e399f66fbc..c768209366 100644 --- a/cargo-miri/src/setup.rs +++ b/cargo-miri/src/setup.rs @@ -160,7 +160,7 @@ pub fn setup( // Do the build. let status = SysrootBuilder::new(&sysroot_dir, target) - .build_mode(BuildMode::Check) + .build_mode(BuildMode::Build) // not a real build, since we use dummy codegen .rustc_version(rustc_version.clone()) .sysroot_config(sysroot_config) .rustflags(rustflags) diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 6ef6e340b3..920fc29481 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -16,7 +16,6 @@ extern crate rustc_hir; extern crate rustc_hir_analysis; extern crate rustc_interface; extern crate rustc_log; -extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; @@ -26,10 +25,8 @@ mod log; use std::env; use std::num::NonZero; use std::ops::Range; -use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use std::sync::Arc; use std::sync::atomic::{AtomicI32, AtomicU32, Ordering}; use miri::{ @@ -51,10 +48,8 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::query::LocalCrate; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::util::Providers; use rustc_session::EarlyDiagCtxt; use rustc_session::config::{CrateType, ErrorOutputType, OptLevel}; -use rustc_session::search_paths::PathKind; use rustc_span::def_id::DefId; use crate::log::setup::{deinit_loggers, init_early_loggers, init_late_loggers}; @@ -126,21 +121,6 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, MiriEntryFnType) { } impl rustc_driver::Callbacks for MiriCompilerCalls { - fn config(&mut self, config: &mut Config) { - config.override_queries = Some(|_, providers| { - providers.extern_queries.used_crate_source = |tcx, cnum| { - let mut providers = Providers::default(); - rustc_metadata::provide(&mut providers); - let mut crate_source = (providers.extern_queries.used_crate_source)(tcx, cnum); - // HACK: rustc will emit "crate ... required to be available in rlib format, but - // was not found in this form" errors once we use `tcx.dependency_formats()` if - // there's no rlib provided, so setting a dummy path here to workaround those errors. - Arc::make_mut(&mut crate_source).rlib = Some((PathBuf::new(), PathKind::All)); - crate_source - }; - }); - } - fn after_analysis<'tcx>( &mut self, _: &rustc_interface::interface::Compiler, @@ -253,12 +233,26 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { #[allow(rustc::potential_query_instability)] // rustc_codegen_ssa (where this code is copied from) also allows this lint fn config(&mut self, config: &mut Config) { if config.opts.prints.is_empty() && self.target_crate { + #[allow(rustc::bad_opt_access)] // tcx does not exist yet + { + let any_crate_types = !config.opts.crate_types.is_empty(); + // Avoid warnings about unsupported crate types. + config + .opts + .crate_types + .retain(|&c| c == CrateType::Executable || c == CrateType::Rlib); + if any_crate_types { + // Assert that we didn't remove all crate types if any crate type was passed on + // the cli. Otherwise we might silently change what kind of crate we are building. + assert!(!config.opts.crate_types.is_empty()); + } + } + // Queries overridden here affect the data stored in `rmeta` files of dependencies, // which will be used later in non-`MIRI_BE_RUSTC` mode. config.override_queries = Some(|_, local_providers| { - // `exported_non_generic_symbols` and `reachable_non_generics` provided by rustc always returns - // an empty result if `tcx.sess.opts.output_types.should_codegen()` is false. - // In addition we need to add #[used] symbols to exported_symbols for `lookup_link_section`. + // We need to add #[used] symbols to exported_symbols for `lookup_link_section`. + // FIXME handle this somehow in rustc itself to avoid this hack. local_providers.exported_non_generic_symbols = |tcx, LocalCrate| { let reachable_set = tcx.with_stable_hashing_context(|hcx| { tcx.reachable_set(()).to_sorted(&hcx, true) diff --git a/src/lib.rs b/src/lib.rs index b756fbb901..bd0f12fd18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,6 +165,7 @@ pub use crate::shims::unwind::{CatchUnwindData, EvalContextExt as _}; /// Also disable the MIR pass that inserts an alignment check on every pointer dereference. Miri /// does that too, and with a better error message. pub const MIRI_DEFAULT_ARGS: &[&str] = &[ + "-Zcodegen-backend=dummy", "--cfg=miri", "-Zalways-encode-mir", "-Zextra-const-ub-checks", diff --git a/test-cargo-miri/Cargo.lock b/test-cargo-miri/Cargo.lock index 3211942618..dd81c3b03b 100644 --- a/test-cargo-miri/Cargo.lock +++ b/test-cargo-miri/Cargo.lock @@ -27,7 +27,6 @@ dependencies = [ "autocfg", "byteorder 0.5.3", "byteorder 1.5.0", - "cdylib", "exported_symbol", "eyre", "issue_1567", @@ -38,13 +37,6 @@ dependencies = [ "proc_macro_crate", ] -[[package]] -name = "cdylib" -version = "0.1.0" -dependencies = [ - "byteorder 1.5.0", -] - [[package]] name = "exported_symbol" version = "0.1.0" diff --git a/test-cargo-miri/Cargo.toml b/test-cargo-miri/Cargo.toml index f5092a4748..3f08f802cf 100644 --- a/test-cargo-miri/Cargo.toml +++ b/test-cargo-miri/Cargo.toml @@ -10,7 +10,6 @@ edition = "2024" [dependencies] byteorder = "1.0" -cdylib = { path = "cdylib" } exported_symbol = { path = "exported-symbol" } proc_macro_crate = { path = "proc-macro-crate" } issue_1567 = { path = "issue-1567" } diff --git a/test-cargo-miri/cdylib/Cargo.toml b/test-cargo-miri/cdylib/Cargo.toml deleted file mode 100644 index 527602e0a8..0000000000 --- a/test-cargo-miri/cdylib/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "cdylib" -version = "0.1.0" -authors = ["Miri Team"] -edition = "2018" - -[lib] -# cargo-miri used to handle `cdylib` crate-type specially (https://github.com/rust-lang/miri/pull/1577). -crate-type = ["cdylib"] - -[dependencies] -byteorder = "1.0" # to test dependencies of sub-crates diff --git a/test-cargo-miri/cdylib/src/lib.rs b/test-cargo-miri/cdylib/src/lib.rs deleted file mode 100644 index e47e588251..0000000000 --- a/test-cargo-miri/cdylib/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -use byteorder::{BigEndian, ByteOrder}; - -#[no_mangle] -extern "C" fn use_the_dependency() { - let _n = ::read_u64(&[1, 2, 3, 4, 5, 6, 7, 8]); -} diff --git a/test-cargo-miri/run.local_crate.stdout.ref b/test-cargo-miri/run.local_crate.stdout.ref index 1587de9ff3..60cd9d371a 100644 --- a/test-cargo-miri/run.local_crate.stdout.ref +++ b/test-cargo-miri/run.local_crate.stdout.ref @@ -1 +1 @@ -subcrate,issue_1567,exported_symbol_dep,test_local_crate_detection,cargo_miri_test,cdylib,exported_symbol,issue_1691,issue_1705,issue_rust_86261,proc_macro_crate +subcrate,issue_1567,exported_symbol_dep,test_local_crate_detection,cargo_miri_test,exported_symbol,issue_1691,issue_1705,issue_rust_86261,proc_macro_crate