From b00696b39d799cbbb95c469a3961842c18e25ffe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 19 Mar 2024 19:35:35 +0100 Subject: [PATCH 1/2] fix compile_fail doctests with post-mono errors --- cargo-miri/src/phases.rs | 2 +- src/bin/miri.rs | 51 ++++++++++++++++++++----- test-cargo-miri/src/lib.rs | 18 +++++++++ test-cargo-miri/test.default.stdout.ref | 6 +-- test-cargo-miri/test.filter.stdout.ref | 2 +- 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/cargo-miri/src/phases.rs b/cargo-miri/src/phases.rs index 81ff68545c..dba3000a80 100644 --- a/cargo-miri/src/phases.rs +++ b/cargo-miri/src/phases.rs @@ -364,7 +364,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let out_filename = out_filename.expect("rustdoc must pass `-o`"); cmd.args(&args); - cmd.env("MIRI_BE_RUSTC", "target"); + cmd.env("MIRI_BE_RUSTC", "rustdoc"); if verbose > 0 { eprintln!( diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 6955e649b4..581e129c9e 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -123,14 +123,31 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { } } +#[derive(Copy, Clone, Debug, PartialEq)] +enum MiriBeRustcMode { + Target, + Host, + Rustdoc, +} + +impl MiriBeRustcMode { + fn target_crate(self) -> bool { + use MiriBeRustcMode::*; + match self { + Target | Rustdoc => true, + Host => false, + } + } +} + struct MiriBeRustCompilerCalls { - target_crate: bool, + mode: MiriBeRustcMode, } 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 { + if config.opts.prints.is_empty() && self.mode == MiriBeRustcMode::Target { // 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| { @@ -179,6 +196,21 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { }); } } + + fn after_analysis<'tcx>( + &mut self, + _: &rustc_interface::interface::Compiler, + queries: &'tcx rustc_interface::Queries<'tcx>, + ) -> Compilation { + queries.global_ctxt().unwrap().enter(|tcx| { + // Make sure compile_fail tests with post-monomorphization const-eval errors work as + // intended in rustdoc mode. + if self.mode == MiriBeRustcMode::Rustdoc { + let _ = tcx.collect_and_partition_mono_items(()); + } + }); + Compilation::Continue + } } fn show_error(msg: &impl std::fmt::Display) -> ! { @@ -351,19 +383,18 @@ fn main() { rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ()); rustc_driver::init_rustc_env_logger(&early_dcx); - let target_crate = if crate_kind == "target" { - true - } else if crate_kind == "host" { - false - } else { - panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}") + let mode = match crate_kind.to_str().unwrap_or_default() { + "target" => MiriBeRustcMode::Target, + "rustdoc" => MiriBeRustcMode::Rustdoc, + "host" => MiriBeRustcMode::Host, + _ => panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}"), }; // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments. run_compiler( args, - target_crate, - &mut MiriBeRustCompilerCalls { target_crate }, + mode.target_crate(), + &mut MiriBeRustCompilerCalls { mode }, using_internal_features, ) } diff --git a/test-cargo-miri/src/lib.rs b/test-cargo-miri/src/lib.rs index 66c8aa2eac..e6b8c4ef65 100644 --- a/test-cargo-miri/src/lib.rs +++ b/test-cargo-miri/src/lib.rs @@ -1,13 +1,31 @@ /// Doc-test test +/// /// ```rust /// assert!(cargo_miri_test::make_true()); /// ``` +/// +/// `no_run` test: +/// /// ```rust,no_run /// assert!(!cargo_miri_test::make_true()); /// ``` +/// +/// `compile_fail` test: +/// /// ```rust,compile_fail /// assert!(cargo_miri_test::make_true() == 5); /// ``` +/// +/// Post-monomorphization error in `compile_fail` test: +/// +/// ```rust,compile_fail +/// struct Fail(T); +/// impl Fail { +/// const C: () = panic!(); +/// } +/// +/// let _val = Fail::::C; +/// ``` #[no_mangle] pub fn make_true() -> bool { issue_1567::use_the_dependency(); diff --git a/test-cargo-miri/test.default.stdout.ref b/test-cargo-miri/test.default.stdout.ref index 9a17f3d61b..922d2120be 100644 --- a/test-cargo-miri/test.default.stdout.ref +++ b/test-cargo-miri/test.default.stdout.ref @@ -10,7 +10,7 @@ running 6 tests test result: ok. 5 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out -running 4 tests -.... -test result: ok. 4 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 diff --git a/test-cargo-miri/test.filter.stdout.ref b/test-cargo-miri/test.filter.stdout.ref index c618956656..5c819dd532 100644 --- a/test-cargo-miri/test.filter.stdout.ref +++ b/test-cargo-miri/test.filter.stdout.ref @@ -13,5 +13,5 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 4 filtered out; finished in $TIME +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out; finished in $TIME From 010d1d7d7a7869227ebc49502bb2291b082e35c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 19 Mar 2024 21:19:30 +0100 Subject: [PATCH 2/2] run full mono-item collection on all MIRI_BE_RUSTC builds --- cargo-miri/src/phases.rs | 2 +- src/bin/miri.rs | 44 ++++++++++++---------------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/cargo-miri/src/phases.rs b/cargo-miri/src/phases.rs index dba3000a80..81ff68545c 100644 --- a/cargo-miri/src/phases.rs +++ b/cargo-miri/src/phases.rs @@ -364,7 +364,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let out_filename = out_filename.expect("rustdoc must pass `-o`"); cmd.args(&args); - cmd.env("MIRI_BE_RUSTC", "rustdoc"); + cmd.env("MIRI_BE_RUSTC", "target"); if verbose > 0 { eprintln!( diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 581e129c9e..8028803dde 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -123,31 +123,14 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { } } -#[derive(Copy, Clone, Debug, PartialEq)] -enum MiriBeRustcMode { - Target, - Host, - Rustdoc, -} - -impl MiriBeRustcMode { - fn target_crate(self) -> bool { - use MiriBeRustcMode::*; - match self { - Target | Rustdoc => true, - Host => false, - } - } -} - struct MiriBeRustCompilerCalls { - mode: MiriBeRustcMode, + target_crate: bool, } 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.mode == MiriBeRustcMode::Target { + if config.opts.prints.is_empty() && self.target_crate { // 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| { @@ -203,11 +186,9 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { queries: &'tcx rustc_interface::Queries<'tcx>, ) -> Compilation { queries.global_ctxt().unwrap().enter(|tcx| { - // Make sure compile_fail tests with post-monomorphization const-eval errors work as - // intended in rustdoc mode. - if self.mode == MiriBeRustcMode::Rustdoc { - let _ = tcx.collect_and_partition_mono_items(()); - } + // We are emulating regular rustc builds, which would perform post-mono const-eval. + // So let's also do that here, even if we might be running with `--emit=metadata`. + let _ = tcx.collect_and_partition_mono_items(()); }); Compilation::Continue } @@ -383,18 +364,19 @@ fn main() { rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ()); rustc_driver::init_rustc_env_logger(&early_dcx); - let mode = match crate_kind.to_str().unwrap_or_default() { - "target" => MiriBeRustcMode::Target, - "rustdoc" => MiriBeRustcMode::Rustdoc, - "host" => MiriBeRustcMode::Host, - _ => panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}"), + let target_crate = if crate_kind == "target" { + true + } else if crate_kind == "host" { + false + } else { + panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}") }; // We cannot use `rustc_driver::main` as we need to adjust the CLI arguments. run_compiler( args, - mode.target_crate(), - &mut MiriBeRustCompilerCalls { mode }, + target_crate, + &mut MiriBeRustCompilerCalls { target_crate }, using_internal_features, ) }