Skip to content

Commit

Permalink
Auto merge of #71631 - RalfJung:miri-unleash-the-gates, r=oli-obk
Browse files Browse the repository at this point in the history
Miri: unleash all feature gates

IMO it is silly to unleash features that do not even have a feature gate yet, but not unleash features that do. The only thing this achieves is making unleashed mode annoying to use as we have to figure out the feature flags to enable (and not always do the error messages say what that flag is).

Given that the point of `-Z unleash-the-miri-inside-of-you` is to debug the Miri internals, I see no good reason for this extra hurdle. I cannot imagine a situation where we'd use that flag, realize the program also requires some feature gate, and then be like "oh I guess if this feature is unstable I will do something else". Instead, we'll always just add that flag to the code as well, so requiring the flag achieves nothing.

r? @oli-obk @ecstatic-morse
Fixes #71630
  • Loading branch information
bors committed May 3, 2020
2 parents 65b4482 + 182133f commit a0c61a9
Show file tree
Hide file tree
Showing 42 changed files with 385 additions and 229 deletions.
2 changes: 1 addition & 1 deletion src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ pub fn run_compiler_in_existing_thread_pool<R>(

let r = {
let _sess_abort_error = OnDrop(|| {
compiler.sess.diagnostic().print_error_count(registry);
compiler.sess.finish_diagnostics(registry);
});

f(&compiler)
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_mir/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@ impl Validator<'mir, 'tcx> {
return;
}

// If an operation is supported in miri (and is not already controlled by a feature gate) it
// can be turned on with `-Zunleash-the-miri-inside-of-you`.
let is_unleashable = O::IS_SUPPORTED_IN_MIRI && O::feature_gate().is_none();
// If an operation is supported in miri it can be turned on with
// `-Zunleash-the-miri-inside-of-you`.
let is_unleashable = O::IS_SUPPORTED_IN_MIRI;

if is_unleashable && self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
self.tcx.sess.span_warn(span, "skipping const checks");
self.tcx.sess.miri_unleashed_feature(span, O::feature_gate());
return;
}

Expand Down
48 changes: 47 additions & 1 deletion src/librustc_session/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ 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};
use rustc_span::SourceFileHashAlgorithm;
use rustc_span::{SourceFileHashAlgorithm, Symbol};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTriple, TlsModel};

use std::cell::{self, RefCell};
Expand Down Expand Up @@ -142,6 +143,12 @@ pub struct Session {
/// and immediately printing the backtrace to stderr.
pub ctfe_backtrace: Lock<CtfeBacktrace>,

/// This tracks where `-Zunleash-the-miri-inside-of-you` was used to get around a
/// const check, optionally with the relevant feature gate. We use this to
/// warn about unleashing, but with a single diagnostic instead of dozens that
/// drown everything else in noise.
miri_unleashed_features: Lock<Vec<(Span, Option<Symbol>)>>,

/// 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).
Expand Down Expand Up @@ -189,6 +196,44 @@ impl From<&'static lint::Lint> for DiagnosticMessageId {
}

impl Session {
pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option<Symbol>) {
self.miri_unleashed_features.lock().push((span, feature_gate));
}

fn check_miri_unleashed_features(&self) {
let unleashed_features = self.miri_unleashed_features.lock();
if !unleashed_features.is_empty() {
let mut must_err = false;
// Create a diagnostic pointing at where things got unleashed.
let mut diag = self.struct_warn("skipping const checks");
for &(span, feature_gate) in unleashed_features.iter() {
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
if let Some(feature_gate) = feature_gate {
diag.span_help(span, &format!("skipping check for `{}` feature", feature_gate));
// The unleash flag must *not* be used to just "hack around" feature gates.
must_err = true;
} else {
diag.span_help(span, "skipping check that does not even have a feature gate");
}
}
diag.emit();
// If we should err, make sure we did.
if must_err && !self.has_errors() {
// We have skipped a feature gate, and not run into other errors... reject.
self.err(
"`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
gates, except when testing error paths in the CTFE engine",
);
}
}
}

/// 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 {
*self.crate_disambiguator.get()
}
Expand Down Expand Up @@ -1139,6 +1184,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,
};

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/consts/const-eval/const_fn_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ const X: fn(usize) -> usize = double;
const X_CONST: fn(usize) -> usize = double_const;

const fn bar(x: usize) -> usize {
X(x) //~ WARNING skipping const checks
X(x)
}

const fn bar_const(x: usize) -> usize {
X_CONST(x) //~ WARNING skipping const checks
X_CONST(x)
}

const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
x(y) //~ WARNING skipping const checks
x(y)
}

fn main() {
Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/consts/const-eval/const_fn_ptr.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr.rs:12:5
|
LL | X(x)
| ^^^^

warning: skipping const checks
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr.rs:16:5
|
LL | X_CONST(x)
| ^^^^^^^^^^

warning: skipping const checks
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr.rs:20:5
|
LL | x(y)
| ^^^^

warning: 3 warnings emitted
warning: 1 warning emitted

1 change: 0 additions & 1 deletion src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const X: fn(usize) -> usize = double;

const fn bar(x: usize) -> usize {
X(x) // FIXME: this should error someday
//~^ WARN: skipping const checks
}

fn main() {}
2 changes: 2 additions & 0 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr_fail.rs:10:5
|
LL | X(x) // FIXME: this should error someday
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn double(x: usize) -> usize {
const X: fn(usize) -> usize = double;

const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
x(y) //~ WARN skipping const checks
x(y)
}

const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
warning: skipping const checks
--> $DIR/const_fn_ptr_fail2.rs:13:5
|
LL | x(y)
| ^^^^

error[E0080]: evaluation of constant expression failed
--> $DIR/const_fn_ptr_fail2.rs:20:5
|
Expand All @@ -24,6 +18,14 @@ LL | assert_eq!(Z, 4);
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const_fn_ptr_fail2.rs:13:5
|
LL | x(y)
| ^^^^

error: aborting due to 2 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0080`.
5 changes: 3 additions & 2 deletions src/test/ui/consts/const-points-to-static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
#![allow(dead_code)]

const TEST: &u8 = &MY_STATIC;
//~^ skipping const checks
//~| it is undefined behavior to use this value
//~^ ERROR it is undefined behavior to use this value
//~| NOTE encountered a reference pointing to a static variable
//~| NOTE

static MY_STATIC: u8 = 4;

Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/consts/const-points-to-static.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
warning: skipping const checks
--> $DIR/const-points-to-static.rs:5:20
|
LL | const TEST: &u8 = &MY_STATIC;
| ^^^^^^^^^

error[E0080]: it is undefined behavior to use this value
--> $DIR/const-points-to-static.rs:5:1
|
Expand All @@ -12,6 +6,14 @@ LL | const TEST: &u8 = &MY_STATIC;
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const-points-to-static.rs:5:20
|
LL | const TEST: &u8 = &MY_STATIC;
| ^^^^^^^^^

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0080`.
1 change: 0 additions & 1 deletion src/test/ui/consts/const-prop-read-static-in-const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![allow(dead_code)]

const TEST: u8 = MY_STATIC; //~ ERROR any use of this value will cause an error
//~^ skipping const checks

static MY_STATIC: u8 = 4;

Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/consts/const-prop-read-static-in-const.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
warning: skipping const checks
--> $DIR/const-prop-read-static-in-const.rs:5:18
|
LL | const TEST: u8 = MY_STATIC;
| ^^^^^^^^^

error: any use of this value will cause an error
--> $DIR/const-prop-read-static-in-const.rs:5:18
|
Expand All @@ -14,5 +8,13 @@ LL | const TEST: u8 = MY_STATIC;
|
= note: `#[deny(const_err)]` on by default

warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/const-prop-read-static-in-const.rs:5:18
|
LL | const TEST: u8 = MY_STATIC;
| ^^^^^^^^^

error: aborting due to previous error; 1 warning emitted

6 changes: 2 additions & 4 deletions src/test/ui/consts/miri_unleashed/abi-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ const extern "C" fn c_fn() {}

const fn call_rust_fn(my_fn: extern "Rust" fn()) {
my_fn();
//~^ WARN skipping const checks
//~| ERROR could not evaluate static initializer
//~^ ERROR could not evaluate static initializer
//~| NOTE calling a function with ABI C using caller ABI Rust
//~| NOTE inside `call_rust_fn`
}

static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
//~^ WARN skipping const checks
//~| NOTE inside `VAL`
//~^ NOTE inside `VAL`

fn main() {}
25 changes: 13 additions & 12 deletions src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
warning: skipping const checks
error[E0080]: could not evaluate static initializer
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^^^
| |
| calling a function with ABI C using caller ABI Rust
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:10:5
...
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:16:18

warning: skipping const checks
--> $DIR/abi-mismatch.rs:17:40
|
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0080]: could not evaluate static initializer
help: skipping check that does not even have a feature gate
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^^^
| |
| calling a function with ABI C using caller ABI Rust
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:10:5
...
help: skipping check that does not even have a feature gate
--> $DIR/abi-mismatch.rs:16:40
|
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:17:18
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error; 2 warnings emitted
error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0080`.
2 changes: 1 addition & 1 deletion src/test/ui/consts/miri_unleashed/assoc_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Foo<T> {
}

trait Bar<T, U: Foo<T>> {
const F: u32 = (U::X, 42).1; //~ WARN skipping const checks
const F: u32 = (U::X, 42).1;
}

impl Foo<u32> for () {
Expand Down
14 changes: 8 additions & 6 deletions src/test/ui/consts/miri_unleashed/assoc_const.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
warning: skipping const checks
--> $DIR/assoc_const.rs:14:20
|
LL | const F: u32 = (U::X, 42).1;
| ^^^^^^^^^^

error[E0080]: erroneous constant used
--> $DIR/assoc_const.rs:31:13
|
LL | let y = <String as Bar<Vec<u32>, String>>::F;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/assoc_const.rs:14:20
|
LL | const F: u32 = (U::X, 42).1;
| ^^^^^^^^^^

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0080`.
5 changes: 2 additions & 3 deletions src/test/ui/consts/miri_unleashed/box.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(const_mut_refs, box_syntax)]
#![feature(box_syntax)]
#![allow(const_err)]

use std::mem::ManuallyDrop;
Expand All @@ -8,7 +8,6 @@ fn main() {}

static TEST_BAD: &mut i32 = {
&mut *(box 0)
//~^ WARN skipping const check
//~| ERROR could not evaluate static initializer
//~^ ERROR could not evaluate static initializer
//~| NOTE heap allocations
};
Loading

0 comments on commit a0c61a9

Please sign in to comment.