From 08ba0145c7801ac57f8ce0d50e9babd1bc7930bc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 2 May 2020 13:19:24 +0200 Subject: [PATCH] make sure the miri-unleash-flag is not used to circumvent feature gates --- .../transform/check_consts/validation.rs | 3 ++ src/librustc_session/session.rs | 37 ++++++++++++++++++- .../miri_unleashed/const_refers_to_static.rs | 4 +- .../const_refers_to_static.stderr | 12 +++--- .../miri_unleashed/read_from_static.stderr | 8 ---- ..._static.rs => read_from_static_mut_ref.rs} | 3 +- 6 files changed, 49 insertions(+), 18 deletions(-) delete mode 100644 src/test/ui/consts/miri_unleashed/read_from_static.stderr rename src/test/ui/consts/{miri_unleashed/read_from_static.rs => read_from_static_mut_ref.rs} (64%) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 712f365e72b..43df0829182 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -254,6 +254,9 @@ impl Validator<'mir, 'tcx> { if is_unleashable && self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { self.tcx.sess.span_warn(self.tcx.def_span(self.def_id), "skipping const checks"); + if let Some(feature) = O::feature_gate() { + self.tcx.sess.miri_unleashed_feature(feature); + } return; } diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 3b7c2f268ce..c99fe173db2 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -21,11 +21,12 @@ use rustc_errors::json::JsonEmitter; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorReported}; use rustc_span::edition::Edition; use rustc_span::source_map::{self, FileLoader, MultiSpan, RealFileLoader, SourceMap, Span}; -use rustc_span::SourceFileHashAlgorithm; +use rustc_span::{SourceFileHashAlgorithm, Symbol}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTriple, TlsModel}; use std::cell::{self, RefCell}; use std::env; +use std::fmt::Write as _; use std::io::Write; use std::num::NonZeroU32; use std::path::PathBuf; @@ -142,6 +143,10 @@ pub struct Session { /// and immediately printing the backtrace to stderr. pub ctfe_backtrace: Lock, + /// This tracks whether `-Zunleash-the-miri-inside-of-you` was used to get around a + /// feature gate. If yes, this file must fail to compile. + miri_unleashed_features: Lock>, + /// Base directory containing the `src/` for the Rust standard library, and /// potentially `rustc` as well, if we can can find it. Right now it's always /// `$sysroot/lib/rustlib/src/rust` (i.e. the `rustup` `rust-src` component). @@ -188,7 +193,36 @@ impl From<&'static lint::Lint> for DiagnosticMessageId { } } +impl Drop for Session { + fn drop(&mut self) { + if !self.has_errors_or_delayed_span_bugs() { + let unleashed_features = self.miri_unleashed_features.get_mut(); + if !unleashed_features.is_empty() { + // Join the strings (itertools has it but libstd does not...) + let mut list = String::new(); + for feature in unleashed_features.iter() { + if !list.is_empty() { + list.push_str(", "); + } + write!(&mut list, "{}", feature).unwrap(); + } + // We have skipped a feature gate, and not run into other errors... reject. + panic!( + "`-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); + } + pub fn local_crate_disambiguator(&self) -> CrateDisambiguator { *self.crate_disambiguator.get() } @@ -1139,6 +1173,7 @@ pub fn build_session_with_source_map( confused_type_with_std_module: Lock::new(Default::default()), system_library_path: OneThread::new(RefCell::new(Default::default())), ctfe_backtrace, + miri_unleashed_features: Lock::new(Default::default()), real_rust_source_base_dir, }; 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 7c8cdaec4a1..0203f13ef61 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,6 +1,8 @@ // 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; @@ -24,7 +26,7 @@ static mut MUTABLE: u32 = 0; const READ_MUT: u32 = unsafe { MUTABLE }; //~^ WARN skipping const checks -fn main() { +pub 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 7e049647cfd..322f98d5445 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:11:1 + --> $DIR/const_refers_to_static.rs:13:1 | LL | / const MUTATE_INTERIOR_MUT: usize = { LL | | @@ -9,7 +9,7 @@ LL | | }; | |__^ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:17:1 + --> $DIR/const_refers_to_static.rs:19:1 | LL | / const READ_INTERIOR_MUT: usize = { LL | | @@ -19,25 +19,25 @@ LL | | }; | |__^ warning: skipping const checks - --> $DIR/const_refers_to_static.rs:24:1 + --> $DIR/const_refers_to_static.rs:26:1 | LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: erroneous constant used - --> $DIR/const_refers_to_static.rs:28:5 + --> $DIR/const_refers_to_static.rs:30:5 | LL | MUTATE_INTERIOR_MUT; | ^^^^^^^^^^^^^^^^^^^ referenced constant has errors error[E0080]: erroneous constant used - --> $DIR/const_refers_to_static.rs:30:5 + --> $DIR/const_refers_to_static.rs:32:5 | LL | READ_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:34:5 | LL | READ_MUT; | ^^^^^^^^ referenced constant has errors diff --git a/src/test/ui/consts/miri_unleashed/read_from_static.stderr b/src/test/ui/consts/miri_unleashed/read_from_static.stderr deleted file mode 100644 index 13646f09a00..00000000000 --- a/src/test/ui/consts/miri_unleashed/read_from_static.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: skipping const checks - --> $DIR/read_from_static.rs:5:1 - | -LL | static OH_YES: &mut i32 = &mut 42; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: 1 warning emitted - diff --git a/src/test/ui/consts/miri_unleashed/read_from_static.rs b/src/test/ui/consts/read_from_static_mut_ref.rs similarity index 64% rename from src/test/ui/consts/miri_unleashed/read_from_static.rs rename to src/test/ui/consts/read_from_static_mut_ref.rs index 4bb0edae5d7..c18227e0f55 100644 --- a/src/test/ui/consts/miri_unleashed/read_from_static.rs +++ b/src/test/ui/consts/read_from_static_mut_ref.rs @@ -1,9 +1,8 @@ // run-pass -// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_mut_refs)] #![allow(const_err)] static OH_YES: &mut i32 = &mut 42; -//~^ WARN skipping const checks fn main() { // Make sure `OH_YES` can be read.