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.](https://github.com/rust-lang/compiler-team/issues/596)

![image](https://github.com/rust-lang/rust/assets/48135649/be661f05-b78a-40a9-b01d-81ad2dbdb690)
This commit is contained in:
bors 2023-10-26 02:08:07 +00:00
commit 6d674af861
15 changed files with 121 additions and 27 deletions

View File

@ -1,5 +1,6 @@
driver_impl_ice = the compiler unexpectedly panicked. this is a bug. driver_impl_ice = the compiler unexpectedly panicked. this is a bug.
driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url} driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url}
driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly
driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden
driver_impl_ice_flags = compiler flags: {$flags} driver_impl_ice_flags = compiler flags: {$flags}

View File

@ -60,7 +60,7 @@ use std::path::PathBuf;
use std::process::{self, Command, Stdio}; use std::process::{self, Command, Stdio};
use std::str; use std::str;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock; use std::sync::{Arc, OnceLock};
use std::time::{Instant, SystemTime}; use std::time::{Instant, SystemTime};
use time::OffsetDateTime; use time::OffsetDateTime;
@ -223,11 +223,18 @@ pub struct RunCompiler<'a, 'b> {
file_loader: Option<Box<dyn FileLoader + Send + Sync>>, file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
make_codegen_backend: make_codegen_backend:
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>, Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
using_internal_features: Arc<std::sync::atomic::AtomicBool>,
} }
impl<'a, 'b> RunCompiler<'a, 'b> { impl<'a, 'b> RunCompiler<'a, 'b> {
pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self { pub fn new(at_args: &'a [String], callbacks: &'b mut (dyn Callbacks + Send)) -> Self {
Self { at_args, callbacks, file_loader: None, make_codegen_backend: None } Self {
at_args,
callbacks,
file_loader: None,
make_codegen_backend: None,
using_internal_features: Arc::default(),
}
} }
/// Set a custom codegen backend. /// Set a custom codegen backend.
@ -259,9 +266,23 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
self self
} }
/// Set the session-global flag that checks whether internal features have been used,
/// suppressing the message about submitting an issue in ICEs when enabled.
#[must_use]
pub fn set_using_internal_features(mut self, using_internal_features: Arc<AtomicBool>) -> Self {
self.using_internal_features = using_internal_features;
self
}
/// Parse args and run the compiler. /// Parse args and run the compiler.
pub fn run(self) -> interface::Result<()> { pub fn run(self) -> interface::Result<()> {
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend) run_compiler(
self.at_args,
self.callbacks,
self.file_loader,
self.make_codegen_backend,
self.using_internal_features,
)
} }
} }
@ -272,6 +293,7 @@ fn run_compiler(
make_codegen_backend: Option< make_codegen_backend: Option<
Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>, Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>,
>, >,
using_internal_features: Arc<std::sync::atomic::AtomicBool>,
) -> interface::Result<()> { ) -> interface::Result<()> {
let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default()); let mut early_error_handler = EarlyErrorHandler::new(ErrorOutputType::default());
@ -316,6 +338,7 @@ fn run_compiler(
override_queries: None, override_queries: None,
make_codegen_backend, make_codegen_backend,
registry: diagnostics_registry(), registry: diagnostics_registry(),
using_internal_features,
expanded_args: args, expanded_args: args,
}; };
@ -1333,8 +1356,12 @@ fn ice_path() -> &'static Option<PathBuf> {
/// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to /// If you have no extra info to report, pass the empty closure `|_| ()` as the argument to
/// extra_info. /// extra_info.
/// ///
/// Returns a flag that can be set to disable the note for submitting a bug. This can be passed to
/// [`RunCompiler::set_using_internal_features`] to let macro expansion set it when encountering
/// internal features.
///
/// A custom rustc driver can skip calling this to set up a custom ICE hook. /// A custom rustc driver can skip calling this to set up a custom ICE hook.
pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) { pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler)) -> Arc<AtomicBool> {
// If the user has not explicitly overridden "RUST_BACKTRACE", then produce // If the user has not explicitly overridden "RUST_BACKTRACE", then produce
// full backtraces. When a compiler ICE happens, we want to gather // full backtraces. When a compiler ICE happens, we want to gather
// as much information as possible to present in the issue opened // 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))
std::env::set_var("RUST_BACKTRACE", "full"); std::env::set_var("RUST_BACKTRACE", "full");
} }
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
let using_internal_features_hook = using_internal_features.clone();
panic::update_hook(Box::new( panic::update_hook(Box::new(
move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static),
info: &PanicInfo<'_>| { info: &PanicInfo<'_>| {
@ -1394,9 +1423,11 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
} }
// Print the ICE message // Print the ICE message
report_ice(info, bug_report_url, extra_info); report_ice(info, bug_report_url, extra_info, &using_internal_features_hook);
}, },
)); ));
using_internal_features
} }
/// Prints the ICE message, including query stack, but without backtrace. /// 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))
/// ///
/// When `install_ice_hook` is called, this function will be called as the panic /// When `install_ice_hook` is called, this function will be called as the panic
/// hook. /// hook.
fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info: fn(&Handler)) { fn report_ice(
info: &panic::PanicInfo<'_>,
bug_report_url: &str,
extra_info: fn(&Handler),
using_internal_features: &AtomicBool,
) {
let fallback_bundle = let fallback_bundle =
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( 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(
handler.emit_err(session_diagnostics::Ice); handler.emit_err(session_diagnostics::Ice);
} }
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url }); if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) {
handler.emit_note(session_diagnostics::IceBugReportInternalFeature);
} else {
handler.emit_note(session_diagnostics::IceBugReport { bug_report_url });
}
let version = util::version_str!().unwrap_or("unknown_version"); let version = util::version_str!().unwrap_or("unknown_version");
let triple = config::host_triple(); let triple = config::host_triple();
@ -1506,7 +1546,7 @@ pub fn main() -> ! {
init_rustc_env_logger(&handler); init_rustc_env_logger(&handler);
signal_handler::install(); signal_handler::install();
let mut callbacks = TimePassesCallbacks::default(); let mut callbacks = TimePassesCallbacks::default();
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ()); let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
let exit_code = catch_with_exit_code(|| { let exit_code = catch_with_exit_code(|| {
let args = env::args_os() let args = env::args_os()
.enumerate() .enumerate()
@ -1516,7 +1556,9 @@ pub fn main() -> ! {
}) })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
RunCompiler::new(&args, &mut callbacks).run() RunCompiler::new(&args, &mut callbacks)
.set_using_internal_features(using_internal_features)
.run()
}); });
if let Some(format) = callbacks.time_passes { if let Some(format) = callbacks.time_passes {

View File

@ -42,6 +42,10 @@ pub(crate) struct IceBugReport<'a> {
pub bug_report_url: &'a str, pub bug_report_url: &'a str,
} }
#[derive(Diagnostic)]
#[diag(driver_impl_ice_bug_report_internal_feature)]
pub(crate) struct IceBugReportInternalFeature;
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(driver_impl_ice_version)] #[diag(driver_impl_ice_version)]
pub(crate) struct IceVersion<'a> { pub(crate) struct IceVersion<'a> {

View File

@ -35,7 +35,7 @@ pub struct StripUnconfigured<'a> {
pub lint_node_id: NodeId, pub lint_node_id: NodeId,
} }
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features { pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -> Features {
fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> { fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> {
if attr.has_name(sym::feature) if attr.has_name(sym::feature)
&& let Some(list) = attr.meta_item_list() && let Some(list) = attr.meta_item_list()
@ -167,6 +167,15 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
// If the declared feature is unstable, record it. // If the declared feature is unstable, record it.
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) { if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
(f.set_enabled)(&mut features); (f.set_enabled)(&mut features);
// When the ICE comes from core, alloc or std (approximation of the standard library), there's a chance
// that the person hitting the ICE may be using -Zbuild-std or similar with an untested target.
// The bug is probably in the standard library and not the compiler in that case, but that doesn't
// really matter - we want a bug report.
if features.internal(name)
&& ![sym::core, sym::alloc, sym::std].contains(&crate_name)
{
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
}
features.set_declared_lang_feature(name, mi.span(), None); features.set_declared_lang_feature(name, mi.span(), None);
continue; continue;
} }

View File

@ -24,6 +24,7 @@ use rustc_span::source_map::{FileLoader, FileName};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use std::path::PathBuf; use std::path::PathBuf;
use std::result; use std::result;
use std::sync::Arc;
pub type Result<T> = result::Result<T, ErrorGuaranteed>; pub type Result<T> = result::Result<T, ErrorGuaranteed>;
@ -410,6 +411,12 @@ pub struct Config {
/// Registry of diagnostics codes. /// Registry of diagnostics codes.
pub registry: Registry, pub registry: Registry,
/// The inner atomic value is set to true when a feature marked as `internal` is
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
/// internal features are wontfix, and they are usually the cause of the ICEs.
/// None signifies that this is not tracked.
pub using_internal_features: Arc<std::sync::atomic::AtomicBool>,
/// All commandline args used to invoke the compiler, with @file args fully expanded. /// All commandline args used to invoke the compiler, with @file args fully expanded.
/// This will only be used within debug info, e.g. in the pdb file on windows /// This will only be used within debug info, e.g. in the pdb file on windows
/// This is mainly useful for other tools that reads that debuginfo to figure out /// 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
config.make_codegen_backend, config.make_codegen_backend,
registry.clone(), registry.clone(),
config.ice_file, config.ice_file,
config.using_internal_features,
config.expanded_args, config.expanded_args,
); );

View File

@ -181,9 +181,11 @@ impl<'tcx> Queries<'tcx> {
feed.crate_name(crate_name); feed.crate_name(crate_name);
let feed = tcx.feed_unit_query(); let feed = tcx.feed_unit_query();
feed.features_query( feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
tcx.arena.alloc(rustc_expand::config::features(sess, &pre_configured_attrs)), sess,
); &pre_configured_attrs,
crate_name,
)));
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs)))); feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
}); });
Ok(qcx) Ok(qcx)

View File

@ -35,6 +35,7 @@ use rustc_target::spec::{RelroLevel, SanitizerSet, SplitDebuginfo, StackProtecto
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc;
type CfgSpecs = FxHashSet<(String, Option<String>)>; type CfgSpecs = FxHashSet<(String, Option<String>)>;
@ -69,6 +70,7 @@ fn mk_session(handler: &mut EarlyErrorHandler, matches: getopts::Matches) -> (Se
None, None,
"", "",
None, None,
Arc::default(),
Default::default(), Default::default(),
); );
(sess, cfg) (sess, cfg)

View File

@ -26,7 +26,7 @@ use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::OnceLock; use std::sync::{Arc, OnceLock};
use std::thread; use std::thread;
/// Function pointer type that constructs a new CodegenBackend. /// Function pointer type that constructs a new CodegenBackend.
@ -71,6 +71,7 @@ pub fn create_session(
>, >,
descriptions: Registry, descriptions: Registry,
ice_file: Option<PathBuf>, ice_file: Option<PathBuf>,
using_internal_features: Arc<AtomicBool>,
expanded_args: Vec<String>, expanded_args: Vec<String>,
) -> (Session, Box<dyn CodegenBackend>) { ) -> (Session, Box<dyn CodegenBackend>) {
let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend { let codegen_backend = if let Some(make_codegen_backend) = make_codegen_backend {
@ -114,6 +115,7 @@ pub fn create_session(
target_override, target_override,
rustc_version_str().unwrap_or("unknown"), rustc_version_str().unwrap_or("unknown"),
ice_file, ice_file,
using_internal_features,
expanded_args, expanded_args,
); );

View File

@ -45,7 +45,7 @@ use std::fmt;
use std::ops::{Div, Mul}; use std::ops::{Div, Mul};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::{atomic::AtomicBool, Arc};
use std::time::Duration; use std::time::Duration;
pub struct OptimizationFuel { pub struct OptimizationFuel {
@ -202,6 +202,12 @@ pub struct Session {
/// The version of the rustc process, possibly including a commit hash and description. /// The version of the rustc process, possibly including a commit hash and description.
pub cfg_version: &'static str, pub cfg_version: &'static str,
/// The inner atomic value is set to true when a feature marked as `internal` is
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
/// internal features are wontfix, and they are usually the cause of the ICEs.
/// None signifies that this is not tracked.
pub using_internal_features: Arc<AtomicBool>,
/// All commandline args used to invoke the compiler, with @file args fully expanded. /// All commandline args used to invoke the compiler, with @file args fully expanded.
/// This will only be used within debug info, e.g. in the pdb file on windows /// This will only be used within debug info, e.g. in the pdb file on windows
/// This is mainly useful for other tools that reads that debuginfo to figure out /// This is mainly useful for other tools that reads that debuginfo to figure out
@ -1389,6 +1395,7 @@ pub fn build_session(
target_override: Option<Target>, target_override: Option<Target>,
cfg_version: &'static str, cfg_version: &'static str,
ice_file: Option<PathBuf>, ice_file: Option<PathBuf>,
using_internal_features: Arc<AtomicBool>,
expanded_args: Vec<String>, expanded_args: Vec<String>,
) -> Session { ) -> Session {
// FIXME: This is not general enough to make the warning lint completely override // FIXME: This is not general enough to make the warning lint completely override
@ -1525,6 +1532,7 @@ pub fn build_session(
target_features: Default::default(), target_features: Default::default(),
unstable_target_features: Default::default(), unstable_target_features: Default::default(),
cfg_version, cfg_version,
using_internal_features,
expanded_args, expanded_args,
}; };

View File

@ -23,6 +23,7 @@ use std::cell::RefCell;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::sync::{atomic::AtomicBool, Arc};
use crate::clean::inline::build_external_trait; use crate::clean::inline::build_external_trait;
use crate::clean::{self, ItemId}; use crate::clean::{self, ItemId};
@ -198,6 +199,7 @@ pub(crate) fn create_config(
.. ..
}: RustdocOptions, }: RustdocOptions,
RenderOptions { document_private, .. }: &RenderOptions, RenderOptions { document_private, .. }: &RenderOptions,
using_internal_features: Arc<AtomicBool>,
) -> rustc_interface::Config { ) -> rustc_interface::Config {
// Add the doc cfg into the doc build. // Add the doc cfg into the doc build.
cfgs.push("doc".to_string()); cfgs.push("doc".to_string());
@ -293,6 +295,7 @@ pub(crate) fn create_config(
make_codegen_backend: None, make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(), registry: rustc_driver::diagnostics_registry(),
ice_file: None, ice_file: None,
using_internal_features,
expanded_args, expanded_args,
} }
} }

View File

@ -110,6 +110,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
make_codegen_backend: None, make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(), registry: rustc_driver::diagnostics_registry(),
ice_file: None, ice_file: None,
using_internal_features: Arc::default(),
expanded_args: options.expanded_args.clone(), expanded_args: options.expanded_args.clone(),
}; };

View File

@ -74,6 +74,7 @@ extern crate jemalloc_sys;
use std::env::{self, VarError}; use std::env::{self, VarError};
use std::io::{self, IsTerminal}; use std::io::{self, IsTerminal};
use std::process; use std::process;
use std::sync::{atomic::AtomicBool, Arc};
use rustc_driver::abort_on_err; use rustc_driver::abort_on_err;
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
@ -157,7 +158,7 @@ pub fn main() {
let mut handler = EarlyErrorHandler::new(ErrorOutputType::default()); let mut handler = EarlyErrorHandler::new(ErrorOutputType::default());
rustc_driver::install_ice_hook( let using_internal_features = rustc_driver::install_ice_hook(
"https://github.com/rust-lang/rust/issues/new\ "https://github.com/rust-lang/rust/issues/new\
?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md", ?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md",
|_| (), |_| (),
@ -177,7 +178,7 @@ pub fn main() {
rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG"); rustc_driver::init_env_logger(&handler, "RUSTDOC_LOG");
let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) { let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&handler) {
Some(args) => main_args(&mut handler, &args), Some(args) => main_args(&mut handler, &args, using_internal_features),
_ => _ =>
{ {
#[allow(deprecated)] #[allow(deprecated)]
@ -701,7 +702,11 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
} }
} }
fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult { fn main_args(
handler: &mut EarlyErrorHandler,
at_args: &[String],
using_internal_features: Arc<AtomicBool>,
) -> MainResult {
// Throw away the first argument, the name of the binary. // Throw away the first argument, the name of the binary.
// In case of at_args being empty, as might be the case by // In case of at_args being empty, as might be the case by
// passing empty argument array to execve under some platforms, // passing empty argument array to execve under some platforms,
@ -752,7 +757,8 @@ fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult
(false, true) => { (false, true) => {
let input = options.input.clone(); let input = options.input.clone();
let edition = options.edition; let edition = options.edition;
let config = core::create_config(handler, options, &render_options); let config =
core::create_config(handler, options, &render_options, using_internal_features);
// `markdown::render` can invoke `doctest::make_test`, which // `markdown::render` can invoke `doctest::make_test`, which
// requires session globals and a thread pool, so we use // requires session globals and a thread pool, so we use
@ -785,7 +791,7 @@ fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult
let scrape_examples_options = options.scrape_examples_options.clone(); let scrape_examples_options = options.scrape_examples_options.clone();
let bin_crate = options.bin_crate; let bin_crate = options.bin_crate;
let config = core::create_config(handler, options, &render_options); let config = core::create_config(handler, options, &render_options, using_internal_features);
interface::run_compiler(config, |compiler| { interface::run_compiler(config, |compiler| {
let sess = compiler.session(); let sess = compiler.session();

View File

@ -178,7 +178,7 @@ pub fn main() {
rustc_driver::init_rustc_env_logger(&handler); rustc_driver::init_rustc_env_logger(&handler);
rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| { let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| {
// FIXME: this macro calls unwrap internally but is called in a panicking context! It's not // FIXME: this macro calls unwrap internally but is called in a panicking context! It's not
// as simple as moving the call from the hook to main, because `install_ice_hook` doesn't // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't
// accept a generic closure. // accept a generic closure.
@ -265,9 +265,11 @@ pub fn main() {
let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package); let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
if clippy_enabled { if clippy_enabled {
args.extend(clippy_args); args.extend(clippy_args);
rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run() rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var })
.set_using_internal_features(using_internal_features).run()
} else { } else {
rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run() rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var })
.set_using_internal_features(using_internal_features).run()
} }
})) }))
} }

View File

@ -241,6 +241,7 @@ fn run_compiler(
mut args: Vec<String>, mut args: Vec<String>,
target_crate: bool, target_crate: bool,
callbacks: &mut (dyn rustc_driver::Callbacks + Send), callbacks: &mut (dyn rustc_driver::Callbacks + Send),
using_internal_features: std::sync::Arc<std::sync::atomic::AtomicBool>
) -> ! { ) -> ! {
if target_crate { if target_crate {
// Miri needs a custom sysroot for target crates. // Miri needs a custom sysroot for target crates.
@ -273,7 +274,8 @@ fn run_compiler(
// Invoke compiler, and handle return code. // Invoke compiler, and handle return code.
let exit_code = rustc_driver::catch_with_exit_code(move || { let exit_code = rustc_driver::catch_with_exit_code(move || {
rustc_driver::RunCompiler::new(&args, callbacks).run() rustc_driver::RunCompiler::new(&args, callbacks)
.set_using_internal_features(using_internal_features).run()
}); });
std::process::exit(exit_code) std::process::exit(exit_code)
} }
@ -295,7 +297,7 @@ fn main() {
// If the environment asks us to actually be rustc, then do that. // If the environment asks us to actually be rustc, then do that.
if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") { if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
// Earliest rustc setup. // Earliest rustc setup.
rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ()); let using_internal_features = rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
rustc_driver::init_rustc_env_logger(&handler); rustc_driver::init_rustc_env_logger(&handler);
let target_crate = if crate_kind == "target" { let target_crate = if crate_kind == "target" {
@ -311,11 +313,12 @@ fn main() {
env::args().collect(), env::args().collect(),
target_crate, target_crate,
&mut MiriBeRustCompilerCalls { target_crate }, &mut MiriBeRustCompilerCalls { target_crate },
using_internal_features,
) )
} }
// Add an ICE bug report hook. // Add an ICE bug report hook.
rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ()); let using_internal_features = rustc_driver::install_ice_hook("https://github.com/rust-lang/miri/issues/new", |_| ());
// Init loggers the Miri way. // Init loggers the Miri way.
init_early_loggers(&handler); init_early_loggers(&handler);
@ -578,5 +581,5 @@ fn main() {
debug!("rustc arguments: {:?}", rustc_args); debug!("rustc arguments: {:?}", rustc_args);
debug!("crate arguments: {:?}", miri_config.args); debug!("crate arguments: {:?}", miri_config.args);
run_compiler(rustc_args, /* target_crate: */ true, &mut MiriCompilerCalls { miri_config }) run_compiler(rustc_args, /* target_crate: */ true, &mut MiriCompilerCalls { miri_config }, using_internal_features)
} }

View File

@ -62,6 +62,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
override_queries: None, override_queries: None,
make_codegen_backend: None, make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(), registry: rustc_driver::diagnostics_registry(),
using_internal_features: std::sync::Arc::default(),
expanded_args: Default::default(), expanded_args: Default::default(),
}; };