@@ -27,7 +27,6 @@ use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, Target, TargetTr
27
27
28
28
use std:: cell:: { self , RefCell } ;
29
29
use std:: env;
30
- use std:: fmt:: Write as _;
31
30
use std:: io:: Write ;
32
31
use std:: num:: NonZeroU32 ;
33
32
use std:: path:: PathBuf ;
@@ -144,9 +143,11 @@ pub struct Session {
144
143
/// and immediately printing the backtrace to stderr.
145
144
pub ctfe_backtrace : Lock < CtfeBacktrace > ,
146
145
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 > ) > > ,
150
151
151
152
/// Base directory containing the `src/` for the Rust standard library, and
152
153
/// 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 {
195
196
}
196
197
197
198
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 ) ) ;
200
201
}
201
202
202
203
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" ) ;
213
217
}
218
+ }
219
+ diag. emit ( ) ;
220
+ // If we should err, make sure we did.
221
+ if must_err && !self . has_errors ( ) {
214
222
// We have skipped a feature gate, and not run into other errors... reject.
215
- self . err ( & format ! (
223
+ self . err (
216
224
"`-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
+ ) ;
221
227
}
222
228
}
223
229
}
0 commit comments