Skip to content

Commit 1b2848b

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 1b2848b

File tree

13 files changed

+108
-23
lines changed

13 files changed

+108
-23
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

+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

+3
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ 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+
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
172+
}
170173
features.set_declared_lang_feature(name, mi.span(), None);
171174
continue;
172175
}

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

src/librustdoc/lib.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ extern crate jemalloc_sys;
7474
use std::env::{self, VarError};
7575
use std::io::{self, IsTerminal};
7676
use std::process;
77+
use std::sync::{atomic::AtomicBool, Arc};
7778

7879
use rustc_driver::abort_on_err;
7980
use rustc_errors::ErrorGuaranteed;
@@ -157,7 +158,7 @@ pub fn main() {
157158

158159
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
159160

160-
rustc_driver::install_ice_hook(
161+
let using_internal_features = rustc_driver::install_ice_hook(
161162
"https://github.com/rust-lang/rust/issues/new\
162163
?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
163164
|_| (),
@@ -177,7 +178,7 @@ pub fn main() {
177178
rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG");
178179

179180
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) {
180-
Some(args) => main_args(&mut handler, &args),
181+
Some(args) => main_args(&mut handler, &args, using_internal_features),
181182
_ =>
182183
{
183184
#[allow(deprecated)]
@@ -701,7 +702,11 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
701702
}
702703
}
703704

704-
fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult {
705+
fn main_args(
706+
handler: &mut EarlyErrorHandler,
707+
at_args: &[String],
708+
using_internal_features: Arc<AtomicBool>,
709+
) -> MainResult {
705710
// Throw away the first argument, the name of the binary.
706711
// In case of at_args being empty, as might be the case by
707712
// passing empty argument array to execve under some platforms,
@@ -752,7 +757,8 @@ fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult
752757
(false, true) => {
753758
let input = options.input.clone();
754759
let edition = options.edition;
755-
let config = core::create_config(handler, options, &render_options);
760+
let config =
761+
core::create_config(handler, options, &render_options, using_internal_features);
756762

757763
// `markdown::render` can invoke `doctest::make_test`, which
758764
// requires session globals and a thread pool, so we use
@@ -785,7 +791,7 @@ fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult
785791
let scrape_examples_options = options.scrape_examples_options.clone();
786792
let bin_crate = options.bin_crate;
787793

788-
let config = core::create_config(handler, options, &render_options);
794+
let config = core::create_config(handler, options, &render_options, using_internal_features);
789795

790796
interface::run_compiler(config, |compiler| {
791797
let sess = compiler.session();

0 commit comments

Comments
 (0)