diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 8e929b7daa8..55f825e150e 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -193,7 +193,7 @@ pub fn run_compiler_in_existing_thread_pool( let r = { let _sess_abort_error = OnDrop(|| { - compiler.sess.diagnostic().print_error_count(registry); + compiler.sess.finish_diagnostics(registry); }); f(&compiler) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 227c221594f..727eb5b333a 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -256,6 +256,8 @@ impl Validator<'mir, 'tcx> { // Use `def_span` to deduplicate all warnings for the same const. self.tcx.sess.span_warn(self.tcx.def_span(self.def_id), "skipping const checks"); if let Some(feature) = O::feature_gate() { + // We'd like to use `delay_span_bug` here, but we cannot as that ICEs + // before codegen has the chance to emit errors. So we use a custom system instead. self.tcx.sess.miri_unleashed_feature(feature); } return; diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index c99fe173db2..3606a5c451a 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -18,6 +18,7 @@ use rustc_data_structures::sync::{ use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter; use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; +use rustc_errors::registry::Registry; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_span::edition::Edition; use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span}; @@ -193,10 +194,14 @@ impl From<&'static lint::Lint> for DiagnosticMessageId { } } -impl Drop for Session { - fn drop(&mut self) { +impl Session { + pub fn miri_unleashed_feature(&self, s: Symbol) { + self.miri_unleashed_features.lock().insert(s); + } + + fn check_miri_unleashed_features(&self) { if !self.has_errors_or_delayed_span_bugs() { - let unleashed_features = self.miri_unleashed_features.get_mut(); + let unleashed_features = self.miri_unleashed_features.lock(); if !unleashed_features.is_empty() { // Join the strings (itertools has it but libstd does not...) let mut list = String::new(); @@ -207,20 +212,20 @@ impl Drop for Session { write!(&mut list, "{}", feature).unwrap(); } // We have skipped a feature gate, and not run into other errors... reject. - panic!( + self.err(&format!( "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \ gates, except when testing error paths in the CTFE engine.\n\ The following feature flags are missing from this crate: {}", list, - ); + )); } } } -} -impl Session { - pub fn miri_unleashed_feature(&self, s: Symbol) { - self.miri_unleashed_features.lock().insert(s); + /// Invoked all the way at the end to finish off diagnostics printing. + pub fn finish_diagnostics(&self, registry: &Registry) { + self.check_miri_unleashed_features(); + self.diagnostic().print_error_count(registry); } pub fn local_crate_disambiguator(&self) -> CrateDisambiguator { diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs b/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs index 0203f13ef61..7c8cdaec4a1 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -1,8 +1,6 @@ // build-fail // compile-flags: -Zunleash-the-miri-inside-of-you -Zdeduplicate-diagnostics #![allow(const_err)] -#![feature(const_raw_ptr_deref)] // FIXME: cannot remove because then rustc thinks there is no error -#![crate_type = "lib"] use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -26,7 +24,7 @@ static mut MUTABLE: u32 = 0; const READ_MUT: u32 = unsafe { MUTABLE }; //~^ WARN skipping const checks -pub fn main() { +fn main() { MUTATE_INTERIOR_MUT; //~^ ERROR: erroneous constant used READ_INTERIOR_MUT; diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index 322f98d5445..7e049647cfd 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -1,5 +1,5 @@ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:13:1 + --> $DIR/const_refers_to_static.rs:11:1 | LL | / const MUTATE_INTERIOR_MUT: usize = { LL | | @@ -9,7 +9,7 @@ LL | | }; | |__^ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:19:1 + --> $DIR/const_refers_to_static.rs:17:1 | LL | / const READ_INTERIOR_MUT: usize = { LL | | @@ -19,25 +19,25 @@ LL | | }; | |__^ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:26:1 + --> $DIR/const_refers_to_static.rs:24:1 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: erroneous constant used - --> $DIR/const_refers_to_static.rs:30:5 + --> $DIR/const_refers_to_static.rs:28:5 | LL | MUTATE_INTERIOR_MUT; | ^^^^^^^^^^^^^^^^^^^ referenced constant has errors error[E0080]: erroneous constant used - --> $DIR/const_refers_to_static.rs:32:5 + --> $DIR/const_refers_to_static.rs:30:5 | LL | READ_INTERIOR_MUT; | ^^^^^^^^^^^^^^^^^ referenced constant has errors error[E0080]: erroneous constant used - --> $DIR/const_refers_to_static.rs:34:5 + --> $DIR/const_refers_to_static.rs:32:5 | LL | READ_MUT; | ^^^^^^^^ referenced constant has errors