Skip to content

Commit 99debec

Browse files
committed
warn about each skipped feature gate
1 parent 89666ab commit 99debec

38 files changed

+343
-345
lines changed

src/librustc_mir/transform/check_consts/validation.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,7 @@ impl Validator<'mir, 'tcx> {
253253
let is_unleashable = O::IS_SUPPORTED_IN_MIRI;
254254

255255
if is_unleashable && self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
256-
// Use `def_span` to deduplicate all warnings for the same const.
257-
self.tcx.sess.span_warn(self.tcx.def_span(self.def_id), "skipping const checks");
258-
if let Some(feature) = O::feature_gate() {
259-
// We'd like to use `delay_span_bug` here, but we cannot as that ICEs
260-
// before codegen has the chance to emit errors. So we use a custom system instead.
261-
self.tcx.sess.miri_unleashed_feature(feature);
262-
}
256+
self.tcx.sess.miri_unleashed_feature(span, O::feature_gate());
263257
return;
264258
}
265259

src/librustc_session/session.rs

+27-21
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTr
2727

2828
use std::cell::{self, RefCell};
2929
use std::env;
30-
use std::fmt::Write as _;
3130
use std::io::Write;
3231
use std::num::NonZeroU32;
3332
use std::path::PathBuf;
@@ -144,9 +143,11 @@ pub struct Session {
144143
/// and immediately printing the backtrace to stderr.
145144
pub ctfe_backtrace: Lock<CtfeBacktrace>,
146145

147-
/// This tracks whether `-Zunleash-the-miri-inside-of-you` was used to get around a
148-
/// feature gate. If yes, this file must fail to compile.
149-
miri_unleashed_features: Lock<FxHashSet<Symbol>>,
146+
/// This tracks where `-Zunleash-the-miri-inside-of-you` was used to get around a
147+
/// const check, optionally with the relevant feature gate. We use this to
148+
/// warn about unleashing, but with a single diagnostic instead of dozens that
149+
/// drown everything else in noise.
150+
miri_unleashed_features: Lock<Vec<(Span, Option<Symbol>)>>,
150151

151152
/// Base directory containing the `src/` for the Rust standard library, and
152153
/// potentially `rustc` as well, if we can can find it. Right now it's always
@@ -195,29 +196,34 @@ impl From<&'static lint::Lint> for DiagnosticMessageId {
195196
}
196197

197198
impl Session {
198-
pub fn miri_unleashed_feature(&self, s: Symbol) {
199-
self.miri_unleashed_features.lock().insert(s);
199+
pub fn miri_unleashed_feature(&self, span: Span, feature_gate: Option<Symbol>) {
200+
self.miri_unleashed_features.lock().push((span, feature_gate));
200201
}
201202

202203
fn check_miri_unleashed_features(&self) {
203-
if !self.has_errors_or_delayed_span_bugs() {
204-
let unleashed_features = self.miri_unleashed_features.lock();
205-
if !unleashed_features.is_empty() {
206-
// Join the strings (itertools has it but libstd does not...)
207-
let mut list = String::new();
208-
for feature in unleashed_features.iter() {
209-
if !list.is_empty() {
210-
list.push_str(", ");
211-
}
212-
write!(&mut list, "{}", feature).unwrap();
204+
let unleashed_features = self.miri_unleashed_features.lock();
205+
if !unleashed_features.is_empty() {
206+
let mut must_err = false;
207+
// Create a diagnostic pointing at where things got unleashed.
208+
let mut diag = self.struct_warn("skipping const checks");
209+
for &(span, feature_gate) in unleashed_features.iter() {
210+
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
211+
if let Some(feature_gate) = feature_gate {
212+
diag.span_help(span, &format!("skipping check for `{}` feature", feature_gate));
213+
// The unleash flag must *not* be used to just "hack around" feature gates.
214+
must_err = true;
215+
} else {
216+
diag.span_help(span, "skipping check that does not even have a feature gate");
213217
}
218+
}
219+
diag.emit();
220+
// If we should err, make sure we did.
221+
if must_err && !self.has_errors() {
214222
// We have skipped a feature gate, and not run into other errors... reject.
215-
self.err(&format!(
223+
self.err(
216224
"`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
217-
gates, except when testing error paths in the CTFE engine.\n\
218-
The following feature flags are missing from this crate: {}",
219-
list,
220-
));
225+
gates, except when testing error paths in the CTFE engine"
226+
);
221227
}
222228
}
223229
}

src/test/ui/consts/const-eval/const_fn_ptr.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ const fn double_const(x: usize) -> usize { x * 2 }
88
const X: fn(usize) -> usize = double;
99
const X_CONST: fn(usize) -> usize = double_const;
1010

11-
const fn bar(x: usize) -> usize { //~ WARNING skipping const checks
11+
const fn bar(x: usize) -> usize {
1212
X(x)
1313
}
1414

15-
const fn bar_const(x: usize) -> usize { //~ WARNING skipping const checks
15+
const fn bar_const(x: usize) -> usize {
1616
X_CONST(x)
1717
}
1818

19-
const fn foo(x: fn(usize) -> usize, y: usize) -> usize { //~ WARNING skipping const checks
19+
const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
2020
x(y)
2121
}
2222

Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
warning: skipping const checks
2-
--> $DIR/const_fn_ptr.rs:11:1
32
|
4-
LL | / const fn bar(x: usize) -> usize {
5-
LL | | X(x)
6-
LL | | }
7-
| |_^
8-
9-
warning: skipping const checks
10-
--> $DIR/const_fn_ptr.rs:15:1
3+
help: skipping check that does not even have a feature gate
4+
--> $DIR/const_fn_ptr.rs:12:5
115
|
12-
LL | / const fn bar_const(x: usize) -> usize {
13-
LL | | X_CONST(x)
14-
LL | | }
15-
| |_^
16-
17-
warning: skipping const checks
18-
--> $DIR/const_fn_ptr.rs:19:1
6+
LL | X(x)
7+
| ^^^^
8+
help: skipping check that does not even have a feature gate
9+
--> $DIR/const_fn_ptr.rs:16:5
10+
|
11+
LL | X_CONST(x)
12+
| ^^^^^^^^^^
13+
help: skipping check that does not even have a feature gate
14+
--> $DIR/const_fn_ptr.rs:20:5
1915
|
20-
LL | / const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
21-
LL | | x(y)
22-
LL | | }
23-
| |_^
16+
LL | x(y)
17+
| ^^^^
2418

25-
warning: 3 warnings emitted
19+
warning: 1 warning emitted
2620

src/test/ui/consts/const-eval/const_fn_ptr_fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
fn double(x: usize) -> usize { x * 2 }
77
const X: fn(usize) -> usize = double;
88

9-
const fn bar(x: usize) -> usize { //~ WARNING skipping const checks
9+
const fn bar(x: usize) -> usize {
1010
X(x) // FIXME: this should error someday
1111
}
1212

Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
warning: skipping const checks
2-
--> $DIR/const_fn_ptr_fail.rs:9:1
32
|
4-
LL | / const fn bar(x: usize) -> usize {
5-
LL | | X(x) // FIXME: this should error someday
6-
LL | | }
7-
| |_^
3+
help: skipping check that does not even have a feature gate
4+
--> $DIR/const_fn_ptr_fail.rs:10:5
5+
|
6+
LL | X(x) // FIXME: this should error someday
7+
| ^^^^
88

99
warning: 1 warning emitted
1010

src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn double(x: usize) -> usize {
99
}
1010
const X: fn(usize) -> usize = double;
1111

12-
const fn bar(x: fn(usize) -> usize, y: usize) -> usize { //~ WARN skipping const checks
12+
const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
1313
x(y)
1414
}
1515

src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
warning: skipping const checks
2-
--> $DIR/const_fn_ptr_fail2.rs:12:1
3-
|
4-
LL | / const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
5-
LL | | x(y)
6-
LL | | }
7-
| |_^
8-
91
error[E0080]: evaluation of constant expression failed
102
--> $DIR/const_fn_ptr_fail2.rs:20:5
113
|
@@ -26,6 +18,14 @@ LL | assert_eq!(Z, 4);
2618
|
2719
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
2820

21+
warning: skipping const checks
22+
|
23+
help: skipping check that does not even have a feature gate
24+
--> $DIR/const_fn_ptr_fail2.rs:13:5
25+
|
26+
LL | x(y)
27+
| ^^^^
28+
2929
error: aborting due to 2 previous errors; 1 warning emitted
3030

3131
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-points-to-static.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
#![allow(dead_code)]
44

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

910
static MY_STATIC: u8 = 4;
1011

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
warning: skipping const checks
2-
--> $DIR/const-points-to-static.rs:5:1
3-
|
4-
LL | const TEST: &u8 = &MY_STATIC;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
71
error[E0080]: it is undefined behavior to use this value
82
--> $DIR/const-points-to-static.rs:5:1
93
|
@@ -12,6 +6,14 @@ LL | const TEST: &u8 = &MY_STATIC;
126
|
137
= 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.
148

9+
warning: skipping const checks
10+
|
11+
help: skipping check that does not even have a feature gate
12+
--> $DIR/const-points-to-static.rs:5:20
13+
|
14+
LL | const TEST: &u8 = &MY_STATIC;
15+
| ^^^^^^^^^
16+
1517
error: aborting due to previous error; 1 warning emitted
1618

1719
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/const-prop-read-static-in-const.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#![allow(dead_code)]
44

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

87
static MY_STATIC: u8 = 4;
98

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
warning: skipping const checks
2-
--> $DIR/const-prop-read-static-in-const.rs:5:1
3-
|
4-
LL | const TEST: u8 = MY_STATIC;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
71
error: any use of this value will cause an error
82
--> $DIR/const-prop-read-static-in-const.rs:5:18
93
|
@@ -14,5 +8,13 @@ LL | const TEST: u8 = MY_STATIC;
148
|
159
= note: `#[deny(const_err)]` on by default
1610

11+
warning: skipping const checks
12+
|
13+
help: skipping check that does not even have a feature gate
14+
--> $DIR/const-prop-read-static-in-const.rs:5:18
15+
|
16+
LL | const TEST: u8 = MY_STATIC;
17+
| ^^^^^^^^^
18+
1719
error: aborting due to previous error; 1 warning emitted
1820

src/test/ui/consts/miri_unleashed/abi-mismatch.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@
77
const extern "C" fn c_fn() {}
88

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

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

2119
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,28 @@
1-
warning: skipping const checks
2-
--> $DIR/abi-mismatch.rs:9:1
3-
|
4-
LL | / const fn call_rust_fn(my_fn: extern "Rust" fn()) {
5-
LL | |
6-
LL | | my_fn();
7-
LL | |
8-
LL | |
9-
LL | |
10-
LL | | }
11-
| |_^
12-
13-
warning: skipping const checks
14-
--> $DIR/abi-mismatch.rs:17:1
15-
|
16-
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18-
191
error[E0080]: could not evaluate static initializer
20-
--> $DIR/abi-mismatch.rs:11:5
2+
--> $DIR/abi-mismatch.rs:10:5
213
|
224
LL | my_fn();
235
| ^^^^^^^
246
| |
257
| calling a function with ABI C using caller ABI Rust
26-
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:11:5
8+
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:10:5
279
...
2810
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
29-
| --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:17:18
11+
| --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:16:18
12+
13+
warning: skipping const checks
14+
|
15+
help: skipping check that does not even have a feature gate
16+
--> $DIR/abi-mismatch.rs:10:5
17+
|
18+
LL | my_fn();
19+
| ^^^^^^^
20+
help: skipping check that does not even have a feature gate
21+
--> $DIR/abi-mismatch.rs:16:40
22+
|
23+
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3025

31-
error: aborting due to previous error; 2 warnings emitted
26+
error: aborting due to previous error; 1 warning emitted
3227

3328
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/miri_unleashed/assoc_const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait Foo<T> {
1111
}
1212

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

1717
impl Foo<u32> for () {
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
warning: skipping const checks
2-
--> $DIR/assoc_const.rs:14:5
3-
|
4-
LL | const F: u32 = (U::X, 42).1;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6-
71
error[E0080]: erroneous constant used
82
--> $DIR/assoc_const.rs:31:13
93
|
104
LL | let y = <String as Bar<Vec<u32>, String>>::F;
115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
126

7+
warning: skipping const checks
8+
|
9+
help: skipping check that does not even have a feature gate
10+
--> $DIR/assoc_const.rs:14:20
11+
|
12+
LL | const F: u32 = (U::X, 42).1;
13+
| ^^^^^^^^^^
14+
1315
error: aborting due to previous error; 1 warning emitted
1416

1517
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/miri_unleashed/box.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::mem::ManuallyDrop;
66

77
fn main() {}
88

9-
static TEST_BAD: &mut i32 = { //~ WARN skipping const checks
9+
static TEST_BAD: &mut i32 = {
1010
&mut *(box 0)
1111
//~^ ERROR could not evaluate static initializer
1212
//~| NOTE heap allocations

0 commit comments

Comments
 (0)