Skip to content

Commit 6d674af

Browse files
committed
Auto merge of #116818 - Nilstrieb:stop-submitting-bug-reports, r=wesleywiser
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. I thought about several ways to do this but now used the explicit threading of an `Arc<AtomicBool>` through `Session`. This is not exactly incremental-safe, but this is fine, as this is set during macro expansion, which is pre-incremental, and also only affects the output of ICEs, at which point incremental correctness doesn't matter much anyways. See [MCP 620.](rust-lang/compiler-team#596) ![image](https://github.com/rust-lang/rust/assets/48135649/be661f05-b78a-40a9-b01d-81ad2dbdb690)
2 parents 278eaf5 + 9d42b1e commit 6d674af

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::OffsetDateTime;
6666

@@ -223,11 +223,18 @@ pub struct RunCompiler<'a, 'b> {
223223
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
224224
make_codegen_backend:
225225
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
226+
using_internal_features: Arc<std::sync::atomic::AtomicBool>,
226227
}
227228

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

233240
/// Set a custom codegen backend.
@@ -259,9 +266,23 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
259266
self
260267
}
261268

269+
/// Set the session-global flag that checks whether internal features have been used,
270+
/// suppressing the message about submitting an issue in ICEs when enabled.
271+
#[must_use]
272+
pub fn set_using_internal_features(mut self, using_internal_features: Arc<AtomicBool>) -> Self {
273+
self.using_internal_features = using_internal_features;
274+
self
275+
}
276+
262277
/// Parse args and run the compiler.
263278
pub fn run(self) -> interface::Result<()> {
264-
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
279+
run_compiler(
280+
self.at_args,
281+
self.callbacks,
282+
self.file_loader,
283+
self.make_codegen_backend,
284+
self.using_internal_features,
285+
)
265286
}
266287
}
267288

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

@@ -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

@@ -1333,8 +1356,12 @@ fn ice_path() -> &'static Option<PathBuf> {
13331356
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
13341357
/// extra_info.
13351358
///
1359+
/// Returns a flag that can be set to disable the note for submitting a bug. This can be passed to
1360+
/// [`RunCompiler::set_using_internal_features`] to let macro expansion set it when encountering
1361+
/// internal features.
1362+
///
13361363
/// A custom rustc driver can skip calling this to set up a custom ICE hook.
1337-
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) {
1364+
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) -> Arc<AtomicBool> {
13381365
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce
13391366
// full backtraces. When a compiler ICE happens, we want to gather
13401367
// as much information as possible to present in the issue opened
@@ -1345,6 +1372,8 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13451372
std::env::set_var("RUST_BACKTRACE", "full");
13461373
}
13471374

1375+
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
1376+
let using_internal_features_hook = using_internal_features.clone();
13481377
panic::update_hook(Box::new(
13491378
move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static),
13501379
info: &PanicInfo<'_>| {
@@ -1394,9 +1423,11 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
13941423
}
13951424

13961425
// Print the ICE message
1397-
report_ice(info, bug_report_url, extra_info);
1426+
report_ice(info, bug_report_url, extra_info, &using_internal_features_hook);
13981427
},
13991428
));
1429+
1430+
using_internal_features
14001431
}
14011432

14021433
/// Prints the ICE message, including query stack, but without backtrace.
@@ -1405,7 +1436,12 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
14051436
///
14061437
/// When `install_ice_hook` is called, this function will be called as the panic
14071438
/// hook.
1408-
fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) {
1439+
fn report_ice(
1440+
info: &panic::PanicInfo<'_>,
1441+
bug_report_url: &str,
1442+
extra_info: fn(&Handler),
1443+
using_internal_features: &AtomicBool,
1444+
) {
14091445
let fallback_bundle =
14101446
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
14111447
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
@@ -1422,7 +1458,11 @@ fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(
14221458
handler.emit_err(session_diagnostics::Ice);
14231459
}
14241460

1425-
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1461+
if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
1462+
handler.emit_note(session_diagnostics::IceBugReportInternalFeature);
1463+
} else {
1464+
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
1465+
}
14261466

14271467
let version = util::version_str!().unwrap_or("unknown_version");
14281468
let triple = config::host_triple();
@@ -1506,7 +1546,7 @@ pub fn main() -> ! {
15061546
init_rustc_env_logger(&handler);
15071547
signal_handler::install();
15081548
let mut callbacks = TimePassesCallbacks::default();
1509-
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1549+
let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
15101550
let exit_code = catch_with_exit_code(|| {
15111551
let args = env::args_os()
15121552
.enumerate()
@@ -1516,7 +1556,9 @@ pub fn main() -> ! {
15161556
})
15171557
})
15181558
.collect::<Vec<_>>();
1519-
RunCompiler::new(&args, &mut callbacks).run()
1559+
RunCompiler::new(&args, &mut callbacks)
1560+
.set_using_internal_features(using_internal_features)
1561+
.run()
15201562
});
15211563

15221564
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
@@ -24,6 +24,7 @@ use rustc_span::source_map::{FileLoader, FileName};
2424
use rustc_span::symbol::sym;
2525
use std::path::PathBuf;
2626
use std::result;
27+
use std::sync::Arc;
2728

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

@@ -410,6 +411,12 @@ pub struct Config {
410411
/// Registry of diagnostics codes.
411412
pub registry: Registry,
412413

414+
/// The inner atomic value is set to true when a feature marked as `internal` is
415+
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
416+
/// internal features are wontfix, and they are usually the cause of the ICEs.
417+
/// None signifies that this is not tracked.
418+
pub using_internal_features: Arc<std::sync::atomic::AtomicBool>,
419+
413420
/// All commandline args used to invoke the compiler, with @file args fully expanded.
414421
/// This will only be used within debug info, e.g. in the pdb file on windows
415422
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -453,6 +460,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
453460
config.make_codegen_backend,
454461
registry.clone(),
455462
config.ice_file,
463+
config.using_internal_features,
456464
config.expanded_args,
457465
);
458466

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
@@ -45,7 +45,7 @@ use std::fmt;
4545
use std::ops::{Div, Mul};
4646
use std::path::{Path, PathBuf};
4747
use std::str::FromStr;
48-
use std::sync::Arc;
48+
use std::sync::{atomic::AtomicBool, Arc};
4949
use std::time::Duration;
5050

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

205+
/// The inner atomic value is set to true when a feature marked as `internal` is
206+
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
207+
/// internal features are wontfix, and they are usually the cause of the ICEs.
208+
/// None signifies that this is not tracked.
209+
pub using_internal_features: Arc<AtomicBool>,
210+
205211
/// All commandline args used to invoke the compiler, with @file args fully expanded.
206212
/// This will only be used within debug info, e.g. in the pdb file on windows
207213
/// This is mainly useful for other tools that reads that debuginfo to figure out
@@ -1389,6 +1395,7 @@ pub fn build_session(
13891395
target_override: Option<Target>,
13901396
cfg_version: &'static str,
13911397
ice_file: Option<PathBuf>,
1398+
using_internal_features: Arc<AtomicBool>,
13921399
expanded_args: Vec<String>,
13931400
) -> Session {
13941401
// FIXME: This is not general enough to make the warning lint completely override
@@ -1525,6 +1532,7 @@ pub fn build_session(
15251532
target_features: Default::default(),
15261533
unstable_target_features: Default::default(),
15271534
cfg_version,
1535+
using_internal_features,
15281536
expanded_args,
15291537
};
15301538

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());
@@ -293,6 +295,7 @@ pub(crate) fn create_config(
293295
make_codegen_backend: None,
294296
registry: rustc_driver::diagnostics_registry(),
295297
ice_file: None,
298+
using_internal_features,
296299
expanded_args,
297300
}
298301
}

src/librustdoc/doctest.rs

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

0 commit comments

Comments
 (0)