Skip to content

Commit 788ae5a

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 788ae5a

File tree

15 files changed

+121
-27
lines changed

15 files changed

+121
-27
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 expected to cause internal compiler errors when used incorrectly
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

+51-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: 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: Arc::default(),
238+
}
232239
}
233240

234241
/// Set a custom codegen backend.
@@ -260,9 +267,23 @@ 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+
#[must_use]
273+
pub fn set_using_internal_features(mut self, using_internal_features: Arc<AtomicBool>) -> Self {
274+
self.using_internal_features = using_internal_features;
275+
self
276+
}
277+
263278
/// Parse args and run the compiler.
264279
pub fn run(self) -> interface::Result<()> {
265-
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
280+
run_compiler(
281+
self.at_args,
282+
self.callbacks,
283+
self.file_loader,
284+
self.make_codegen_backend,
285+
self.using_internal_features,
286+
)
266287
}
267288
}
268289

@@ -273,6 +294,7 @@ fn run_compiler(
273294
make_codegen_backend: Option<
274295
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
275296
>,
297+
using_internal_features: Arc<std::sync::atomic::AtomicBool>,
276298
) -> interface::Result<()> {
277299
let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
278300

@@ -316,6 +338,7 @@ fn run_compiler(
316338
override_queries: None,
317339
make_codegen_backend,
318340
registry: diagnostics_registry(),
341+
using_internal_features,
319342
expanded_args: args,
320343
};
321344

@@ -1323,8 +1346,12 @@ fn ice_path() -> &'static Option<PathBuf> {
13231346
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
13241347
/// extra_info.
13251348
///
1349+
/// Returns a flag that can be set to disable the note for submitting a bug. This can be passed to
1350+
/// [`RunCompiler::set_using_internal_features`] to let macro expansion set it when encountering
1351+
/// internal features.
1352+
///
13261353
/// 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)) {
1354+
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) -> Arc<AtomicBool> {
13281355
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
13291356
// full backtraces. When a compiler ICE happens, we want to gather
13301357
// as much information as possible to present in the issue opened
@@ -1335,6 +1362,8 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13351362
std::env::set_var("RUST_BACKTRACE", "full");
13361363
}
13371364

1365+
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
1366+
let using_internal_features_hook = using_internal_features.clone();
13381367
panic::update_hook(Box::new(
13391368
move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static),
13401369
info: &PanicInfo<'_>| {
@@ -1384,9 +1413,11 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13841413
}
13851414

13861415
// Print the ICE message
1387-
report_ice(info, bug_report_url, extra_info);
1416+
report_ice(info, bug_report_url, extra_info, &using_internal_features_hook);
13881417
},
13891418
));
1419+
1420+
using_internal_features
13901421
}
13911422

13921423
/// Prints the ICE message, including query stack, but without backtrace.
@@ -1395,7 +1426,12 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13951426
///
13961427
/// When `install_ice_hook` is called, this function will be called as the panic
13971428
/// hook.
1398-
fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) {
1429+
fn report_ice(
1430+
info: &panic::PanicInfo<'_>,
1431+
bug_report_url: &str,
1432+
extra_info: fn(&Handler),
1433+
using_internal_features: &AtomicBool,
1434+
) {
13991435
let fallback_bundle =
14001436
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
14011437
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
@@ -1412,7 +1448,11 @@ fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(
14121448
handler.emit_err(session_diagnostics::Ice);
14131449
}
14141450

1415-
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1451+
if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
1452+
handler.emit_note(session_diagnostics::IceBugReportInternalFeature);
1453+
} else {
1454+
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1455+
}
14161456

14171457
let version = util::version_str!().unwrap_or("unknown_version");
14181458
let triple = config::host_triple();
@@ -1496,7 +1536,7 @@ pub fn main() -> ! {
14961536
init_rustc_env_logger(&handler);
14971537
signal_handler::install();
14981538
let mut callbacks = TimePassesCallbacks::default();
1499-
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1539+
let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
15001540
let exit_code = catch_with_exit_code(|| {
15011541
let args = env::args_os()
15021542
.enumerate()
@@ -1506,7 +1546,9 @@ pub fn main() -> ! {
15061546
})
15071547
})
15081548
.collect::<Vec<_>>();
1509-
RunCompiler::new(&args, &mut callbacks).run()
1549+
RunCompiler::new(&args, &mut callbacks)
1550+
.set_using_internal_features(using_internal_features)
1551+
.run()
15101552
});
15111553

15121554
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

+10-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub struct StripUnconfigured<'a> {
3535
pub lint_node_id: NodeId,
3636
}
3737

38-
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
38+
pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -> Features {
3939
fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> {
4040
if attr.has_name(sym::feature)
4141
&& let Some(list) = attr.meta_item_list()
@@ -167,6 +167,15 @@ 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+
// When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance
171+
// that the person hitting the ICE may be using -Zbuild-std or similar with an untested target.
172+
// The bug is probably in the standard library and not the compiler in that case, but that doesn't
173+
// really matter - we want a bug report.
174+
if features.internal(name)
175+
&& ![sym::core, sym::alloc, sym::std].contains(&crate_name)
176+
{
177+
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
178+
}
170179
features.set_declared_lang_feature(name, mi.span(), None);
171180
continue;
172181
}

compiler/rustc_interface/src/interface.rs

+8
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,12 @@ pub struct Config {
280281
/// Registry of diagnostics codes.
281282
pub registry: Registry,
282283

284+
/// The inner atomic value is set to true when a feature marked as `internal` is
285+
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
286+
/// internal features are wontfix, and they are usually the cause of the ICEs.
287+
/// None signifies that this is not tracked.
288+
pub using_internal_features: Arc<std::sync::atomic::AtomicBool>,
289+
283290
/// All commandline args used to invoke the compiler, with @file args fully expanded.
284291
/// This will only be used within debug info, e.g. in the pdb file on windows
285292
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -323,6 +330,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
323330
config.make_codegen_backend,
324331
registry.clone(),
325332
config.ice_file,
333+
config.using_internal_features,
326334
config.expanded_args,
327335
);
328336

compiler/rustc_interface/src/queries.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,11 @@ impl<'tcx> Queries<'tcx> {
181181
feed.crate_name(crate_name);
182182

183183
let feed = tcx.feed_unit_query();
184-
feed.features_query(
185-
tcx.arena.alloc(rustc_expand::config::features(sess, &pre_configured_attrs)),
186-
);
184+
feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
185+
sess,
186+
&pre_configured_attrs,
187+
crate_name,
188+
)));
187189
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
188190
});
189191
Ok(qcx)

compiler/rustc_interface/src/tests.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtecto
3535
use std::collections::{BTreeMap, BTreeSet};
3636
use std::num::NonZeroUsize;
3737
use std::path::{Path, PathBuf};
38+
use std::sync::Arc;
3839

3940
type CfgSpecs = FxHashSet<(String, Option<String>)>;
4041

@@ -69,6 +70,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
6970
None,
7071
"",
7172
None,
73+
Arc::default(),
7274
Default::default(),
7375
);
7476
(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: 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

+9-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,12 @@ 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+
/// The inner atomic value is set to true when a feature marked as `internal` is
205+
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
206+
/// internal features are wontfix, and they are usually the cause of the ICEs.
207+
/// None signifies that this is not tracked.
208+
pub using_internal_features: Arc<AtomicBool>,
209+
204210
/// All commandline args used to invoke the compiler, with @file args fully expanded.
205211
/// This will only be used within debug info, e.g. in the pdb file on windows
206212
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -1333,6 +1339,7 @@ pub fn build_session(
13331339
target_override: Option<Target>,
13341340
cfg_version: &'static str,
13351341
ice_file: Option<PathBuf>,
1342+
using_internal_features: Arc<AtomicBool>,
13361343
expanded_args: Vec<String>,
13371344
) -> Session {
13381345
// FIXME: This is not general enough to make the warning lint completely override
@@ -1469,6 +1476,7 @@ pub fn build_session(
14691476
target_features: Default::default(),
14701477
unstable_target_features: Default::default(),
14711478
cfg_version,
1479+
using_internal_features,
14721480
expanded_args,
14731481
};
14741482

src/librustdoc/core.rs

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::cell::RefCell;
2323
use std::mem;
2424
use std::rc::Rc;
2525
use std::sync::LazyLock;
26+
use std::sync::{atomic::AtomicBool, Arc};
2627

2728
use crate::clean::inline::build_external_trait;
2829
use crate::clean::{self, ItemId};
@@ -198,6 +199,7 @@ pub(crate) fn create_config(
198199
..
199200
}: RustdocOptions,
200201
RenderOptions { document_private, .. }: &RenderOptions,
202+
using_internal_features: Arc<AtomicBool>,
201203
) -> rustc_interface::Config {
202204
// Add the doc cfg into the doc build.
203205
cfgs.push("doc".to_string());
@@ -292,6 +294,7 @@ pub(crate) fn create_config(
292294
make_codegen_backend: None,
293295
registry: rustc_driver::diagnostics_registry(),
294296
ice_file: None,
297+
using_internal_features,
295298
expanded_args,
296299
}
297300
}

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: Arc::default(),
112113
expanded_args: options.expanded_args.clone(),
113114
};
114115

0 commit comments

Comments
 (0)