Skip to content

Commit 9b125b5

Browse files
committed
Stop telling people to submit bugs for internal feature ICEs
This keeps track of usage of internal features, and changes the message to instead tell them that using internal features is not supported. See MCP 620.
1 parent 98c1e3d commit 9b125b5

File tree

14 files changed

+93
-15
lines changed

14 files changed

+93
-15
lines changed

compiler/rustc_driver_impl/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
22
driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
3+
driver_impl_ice_bug_report_internal_feature = using internal features is not supported and is expected to lead to internal compiler errors
34
driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
45
56
driver_impl_ice_flags = compiler flags: {$flags}

compiler/rustc_driver_impl/src/lib.rs

+57-9
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use std::path::PathBuf;
6060
use std::process::{self, Command, Stdio};
6161
use std::str;
6262
use std::sync::atomic::{AtomicBool, Ordering};
63-
use std::sync::OnceLock;
63+
use std::sync::{Arc, OnceLock};
6464
use std::time::{Instant, SystemTime};
6565
use time::format_description::well_known::Rfc3339;
6666
use time::OffsetDateTime;
@@ -224,11 +224,18 @@ pub struct RunCompiler<'a, 'b> {
224224
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
225225
make_codegen_backend:
226226
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
227+
using_internal_features: Option<Arc<std::sync::atomic::AtomicBool>>,
227228
}
228229

229230
impl<'a, 'b> RunCompiler<'a, 'b> {
230231
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
231-
Self { at_args, callbacks, file_loader: None, make_codegen_backend: None }
232+
Self {
233+
at_args,
234+
callbacks,
235+
file_loader: None,
236+
make_codegen_backend: None,
237+
using_internal_features: None,
238+
}
232239
}
233240

234241
/// Set a custom codegen backend.
@@ -260,9 +267,25 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
260267
self
261268
}
262269

270+
/// Set the session-global flag that checks whether internal features have been used,
271+
/// suppressing the message about submitting an issue in ICEs when enabled.
272+
pub fn set_using_internal_features(
273+
&mut self,
274+
using_internal_features: Option<Arc<AtomicBool>>,
275+
) -> &mut Self {
276+
self.using_internal_features = using_internal_features;
277+
self
278+
}
279+
263280
/// Parse args and run the compiler.
264281
pub fn run(self) -> interface::Result<()> {
265-
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
282+
run_compiler(
283+
self.at_args,
284+
self.callbacks,
285+
self.file_loader,
286+
self.make_codegen_backend,
287+
self.using_internal_features,
288+
)
266289
}
267290
}
268291

@@ -273,6 +296,7 @@ fn run_compiler(
273296
make_codegen_backend: Option<
274297
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
275298
>,
299+
using_internal_features: Option<Arc<std::sync::atomic::AtomicBool>>,
276300
) -> interface::Result<()> {
277301
let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
278302

@@ -316,6 +340,7 @@ fn run_compiler(
316340
override_queries: None,
317341
make_codegen_backend,
318342
registry: diagnostics_registry(),
343+
using_internal_features,
319344
expanded_args: args,
320345
};
321346

@@ -1323,8 +1348,16 @@ fn ice_path() -> &'static Option<PathBuf> {
13231348
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
13241349
/// extra_info.
13251350
///
1351+
/// If emitting the "please submit a bug" message is fine when internal features are enabled, `None`
1352+
/// can be passed as the `using_internal_features`. To hide the note, pass in a bool that is also passed
1353+
/// to [`RunCompiler::set_using_internal_features`].
1354+
///
13261355
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
1327-
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) {
1356+
pub fn install_ice_hook(
1357+
bug_report_url: &'static str,
1358+
extra_info: fn(&Handler),
1359+
using_internal_features: Option<Arc<AtomicBool>>,
1360+
) {
13281361
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
13291362
// full backtraces. When a compiler ICE happens, we want to gather
13301363
// as much information as possible to present in the issue opened
@@ -1384,7 +1417,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13841417
}
13851418

13861419
// Print the ICE message
1387-
report_ice(info, bug_report_url, extra_info);
1420+
report_ice(info, bug_report_url, extra_info, using_internal_features.clone());
13881421
},
13891422
));
13901423
}
@@ -1395,7 +1428,12 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13951428
///
13961429
/// When `install_ice_hook` is called, this function will be called as the panic
13971430
/// hook.
1398-
fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) {
1431+
fn report_ice(
1432+
info: &panic::PanicInfo<'_>,
1433+
bug_report_url: &str,
1434+
extra_info: fn(&Handler),
1435+
using_internal_features: Option<Arc<AtomicBool>>,
1436+
) {
13991437
let fallback_bundle =
14001438
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
14011439
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
@@ -1412,7 +1450,13 @@ fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(
14121450
handler.emit_err(session_diagnostics::Ice);
14131451
}
14141452

1415-
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1453+
if using_internal_features
1454+
.map_or(false, |internal| internal.load(std::sync::atomic::Ordering::Relaxed))
1455+
{
1456+
handler.emit_note(session_diagnostics::IceBugReportInternalFeature);
1457+
} else {
1458+
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1459+
}
14161460

14171461
let version = util::version_str!().unwrap_or("unknown_version");
14181462
let triple = config::host_triple();
@@ -1493,10 +1537,12 @@ pub fn main() -> ! {
14931537

14941538
let handler = EarlyErrorHandler::new(ErrorOutputType::default());
14951539

1540+
let using_internal_features = Some(Arc::default());
1541+
14961542
init_rustc_env_logger(&handler);
14971543
signal_handler::install();
14981544
let mut callbacks = TimePassesCallbacks::default();
1499-
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1545+
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| (), using_internal_features.clone());
15001546
let exit_code = catch_with_exit_code(|| {
15011547
let args = env::args_os()
15021548
.enumerate()
@@ -1506,7 +1552,9 @@ pub fn main() -> ! {
15061552
})
15071553
})
15081554
.collect::<Vec<_>>();
1509-
RunCompiler::new(&args, &mut callbacks).run()
1555+
let mut run = RunCompiler::new(&args, &mut callbacks);
1556+
run.set_using_internal_features(using_internal_features);
1557+
run.run()
15101558
});
15111559

15121560
if let Some(format) = callbacks.time_passes {

compiler/rustc_driver_impl/src/session_diagnostics.rs

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ pub(crate) struct IceBugReport<'a> {
4242
pub bug_report_url: &'a str,
4343
}
4444

45+
#[derive(Diagnostic)]
46+
#[diag(driver_impl_ice_bug_report_internal_feature)]
47+
pub(crate) struct IceBugReportInternalFeature;
48+
4549
#[derive(Diagnostic)]
4650
#[diag(driver_impl_ice_version)]
4751
pub(crate) struct IceVersion<'a> {

compiler/rustc_expand/src/config.rs

+5
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
167167
// If the declared feature is unstable, record it.
168168
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
169169
(f.set_enabled)(&mut features);
170+
if features.internal(name) {
171+
if let Some(using_internal_features) = &sess.using_internal_features {
172+
using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
173+
}
174+
}
170175
features.set_declared_lang_feature(name, mi.span(), None);
171176
continue;
172177
}

compiler/rustc_interface/src/interface.rs

+7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_span::source_map::{FileLoader, FileName};
2323
use rustc_span::symbol::sym;
2424
use std::path::PathBuf;
2525
use std::result;
26+
use std::sync::Arc;
2627

2728
pub type Result<T> = result::Result<T, ErrorGuaranteed>;
2829

@@ -280,6 +281,11 @@ pub struct Config {
280281
/// Registry of diagnostics codes.
281282
pub registry: Registry,
282283

284+
/// Enabled when a feature marked as `internal` is enabled. Makes it so that
285+
/// "please report a bug" is hidden, as ICEs with internal features are wontfix,
286+
/// and they are usually the cause of the ICEs.
287+
pub using_internal_features: Option<Arc<std::sync::atomic::AtomicBool>>,
288+
283289
/// All commandline args used to invoke the compiler, with @file args fully expanded.
284290
/// This will only be used within debug info, e.g. in the pdb file on windows
285291
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -323,6 +329,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
323329
config.make_codegen_backend,
324330
registry.clone(),
325331
config.ice_file,
332+
config.using_internal_features,
326333
config.expanded_args,
327334
);
328335

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
6969
None,
7070
"",
7171
None,
72+
None,
7273
Default::default(),
7374
);
7475
(sess, cfg)

compiler/rustc_interface/src/util.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
2626
use std::mem;
2727
use std::path::{Path, PathBuf};
2828
use std::sync::atomic::{AtomicBool, Ordering};
29-
use std::sync::OnceLock;
29+
use std::sync::{Arc, OnceLock};
3030
use std::thread;
3131

3232
/// Function pointer type that constructs a new CodegenBackend.
@@ -71,6 +71,7 @@ pub fn create_session(
7171
>,
7272
descriptions: Registry,
7373
ice_file: Option<PathBuf>,
74+
using_internal_features: Option<Arc<AtomicBool>>,
7475
expanded_args: Vec<String>,
7576
) -> (Session, Box<dyn CodegenBackend>) {
7677
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
@@ -114,6 +115,7 @@ pub fn create_session(
114115
target_override,
115116
rustc_version_str().unwrap_or("unknown"),
116117
ice_file,
118+
using_internal_features,
117119
expanded_args,
118120
);
119121

compiler/rustc_session/src/session.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::fmt;
4444
use std::ops::{Div, Mul};
4545
use std::path::{Path, PathBuf};
4646
use std::str::FromStr;
47-
use std::sync::Arc;
47+
use std::sync::{atomic::AtomicBool, Arc};
4848
use std::time::Duration;
4949

5050
pub struct OptimizationFuel {
@@ -201,6 +201,11 @@ pub struct Session {
201201
/// The version of the rustc process, possibly including a commit hash and description.
202202
pub cfg_version: &'static str,
203203

204+
/// Enabled when a feature marked as `internal` is enabled. Makes it so that
205+
/// "please report a bug" is hidden, as ICEs with internal features are wontfix,
206+
/// and they are usually the cause of the ICEs.
207+
pub using_internal_features: Option<Arc<AtomicBool>>,
208+
204209
/// All commandline args used to invoke the compiler, with @file args fully expanded.
205210
/// This will only be used within debug info, e.g. in the pdb file on windows
206211
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -1333,6 +1338,7 @@ pub fn build_session(
13331338
target_override: Option<Target>,
13341339
cfg_version: &'static str,
13351340
ice_file: Option<PathBuf>,
1341+
using_internal_features: Option<Arc<AtomicBool>>,
13361342
expanded_args: Vec<String>,
13371343
) -> Session {
13381344
// FIXME: This is not general enough to make the warning lint completely override
@@ -1469,6 +1475,7 @@ pub fn build_session(
14691475
target_features: Default::default(),
14701476
unstable_target_features: Default::default(),
14711477
cfg_version,
1478+
using_internal_features,
14721479
expanded_args,
14731480
};
14741481

src/librustdoc/core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ pub(crate) fn create_config(
292292
make_codegen_backend: None,
293293
registry: rustc_driver::diagnostics_registry(),
294294
ice_file: None,
295+
using_internal_features: None,
295296
expanded_args,
296297
}
297298
}

src/librustdoc/doctest.rs

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
109109
make_codegen_backend: None,
110110
registry: rustc_driver::diagnostics_registry(),
111111
ice_file: None,
112+
using_internal_features: None,
112113
expanded_args: options.expanded_args.clone(),
113114
};
114115

src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ pub fn main() {
161161
"https://github.com/rust-lang/rust/issues/new\
162162
?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
163163
|_| (),
164+
None,
164165
);
165166

166167
// When using CI artifacts with `download-rustc`, tracing is unconditionally built

src/tools/clippy/src/driver.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub fn main() {
184184
// accept a generic closure.
185185
let version_info = rustc_tools_util::get_version_info!();
186186
handler.note_without_error(format!("Clippy version: {version_info}"));
187-
});
187+
}, None);
188188

189189
exit(rustc_driver::catch_with_exit_code(move || {
190190
let mut orig_args: Vec<String> = env::args().collect();

src/tools/miri/src/bin/miri.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ fn main() {
295295
// If the environment asks us to actually be rustc, then do that.
296296
if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
297297
// Earliest rustc setup.
298-
rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
298+
rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| (), None);
299299
rustc_driver::init_rustc_env_logger(&handler);
300300

301301
let target_crate = if crate_kind == "target" {
@@ -315,7 +315,7 @@ fn main() {
315315
}
316316

317317
// Add an ICE bug report hook.
318-
rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ());
318+
rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| (), None);
319319

320320
// Init loggers the Miri way.
321321
init_early_loggers(&handler);

src/tools/rustfmt/src/bin/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rustfmt/issues/new?la
2727
extern crate rustc_driver;
2828

2929
fn main() {
30-
rustc_driver::install_ice_hook(BUG_REPORT_URL, |_| ());
30+
rustc_driver::install_ice_hook(BUG_REPORT_URL, |_| (), None);
3131

3232
env_logger::Builder::from_env("RUSTFMT_LOG").init();
3333
let opts = make_opts();

0 commit comments

Comments
 (0)