Change:
slightly increased default binary size (checked on x8664-pc-windows-msvc), the reason is now code unconditionally includes File::open (~ 2kb out of 130) and friends. can be tracked back by new imports of , for where is Originally posted by in
cc
cc -- I'm surprised that didn't include any libs review in the first place, having modified the default panic hook. Maybe ought to be registering its own panic hook instead?
Size changed back to 123kb.

Discussion:
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(lazy_cell)] #![feature(decl_macro)] <del> #![feature(ice_to_disk)] </del> <ins> #![feature(panic_update_hook)] </ins> #![feature(let_chains)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)]

use std::env; use std::ffi::OsString; use std::fmt::Write as _; <del> use std::fs; </del> <ins> use std::fs::{self, File}; </ins> use std::io::{self, IsTerminal, Read, Write}; <del> use std::panic::{self, catch_unwind}; </del> <ins> use std::panic::{self, catch_unwind, PanicInfo}; </ins> use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str;

std::env::set_var("RUST_BACKTRACE", "full"); } <del> panic::set_hook(Box::new(move |info| { // If the error was caused by a broken pipe then this is not a bug. // Write the error and return immediately. See #98700. #[cfg(windows)] if let Some(msg) = info.payload().downcast_ref::<String>() { if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") { // the error code is already going to be reported when the panic unwinds up the stack let handler = EarlyErrorHandler::new(ErrorOutputType::default()); let _ = handler.early_error_no_abort(msg.clone()); return; } }; // Invoke the default handler, which prints the actual panic message and optionally a backtrace // Don't do this for delayed bugs, which already emit their own more useful backtrace. if !info.payload().is::<rustc_errors::DelayedBugPanic>() { std::panic_hook_with_disk_dump(info, ice_path().as_deref()); </del> <ins> panic::update_hook(Box::new( move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), info: &PanicInfo<'_>| { // If the error was caused by a broken pipe then this is not a bug. // Write the error and return immediately. See #98700. #[cfg(windows)] if let Some(msg) = info.payload().downcast_ref::<String>() { if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") { // the error code is already going to be reported when the panic unwinds up the stack let handler = EarlyErrorHandler::new(ErrorOutputType::default()); let _ = handler.early_error_no_abort(msg.clone()); return; } }; </ins> <del> // Separate the output with an empty line eprintln!(); } </del> <ins> // Invoke the default handler, which prints the actual panic message and optionally a backtrace // Don't do this for delayed bugs, which already emit their own more useful backtrace. if !info.payload().is::<rustc_errors::DelayedBugPanic>() { default_hook(info); // Separate the output with an empty line eprintln!(); if let Some(ice_path) = ice_path() && let Ok(mut out) = File::options().create(true).append(true).open(&ice_path) { // The current implementation always returns `Some`. let location = info.location().unwrap(); let msg = match info.payload().downcast_ref::<&'static str>() { Some(s) => *s, None => match info.payload().downcast_ref::<String>() { Some(s) => &s[..], None => "Box<dyn Any>", }, }; let thread = std::thread::current(); let name = thread.name().unwrap_or("<unnamed>"); let _ = write!( &mut out, "thread '{name}' panicked at {location}:n {msg}n stack backtrace:n {:#}", std::backtrace::Backtrace::force_capture() ); } } </ins> <del> // Print the ICE message report_ice(info, bug_report_url, extra_info); })); </del> <ins> // Print the ICE message report_ice(info, bug_report_url, extra_info); }, )); </ins> } /// Prints the ICE message, including query stack, but without backtrace.

// Private support modules mod panicking; <del> #[unstable(feature = "ice_to_disk", issue = "none")] pub use panicking::panic_hook_with_disk_dump; </del> #[path = "../../backtrace/src/lib.rs"] #[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] mod backtrace_rs;

/// The default panic handler. fn default_hook(info: &PanicInfo<'_>) { <del> panic_hook_with_disk_dump(info, None) } #[unstable(feature = "ice_to_disk", issue = "none")] /// The implementation of the default panic handler. /// /// It can also write the backtrace to a given `path`. This functionality is used only by `rustc`. pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path::Path>) { </del> // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. let backtrace = if info.force_no_backtrace() {

let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>"); <del> let write = |err: &mut dyn crate::io::Write, backtrace: Option<BacktraceStyle>| { </del> <ins> let write = |err: &mut dyn crate::io::Write| { </ins> let _ = writeln!(err, "thread '{name}' panicked at {location}:n{msg}"); static FIRST_PANIC: AtomicBool = AtomicBool::new(true);

} Some(BacktraceStyle::Off) => { if FIRST_PANIC.swap(false, Ordering::SeqCst) { <del> if let Some(path) = path { let _ = writeln!( err, "note: a backtrace for this error was stored at `{}`", path.display(), ); } else { let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` environment variable to display a  </del> <ins> let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` environment variable to display a  </ins> backtrace" <del> ); } </del> <ins> ); </ins> } } // If backtraces aren't supported or are forced-off, do nothing.

} }; <del> if let Some(path) = path && let Ok(mut out) = crate::fs::File::options().create(true).append(true).open(&path) { write(&mut out, BacktraceStyle::full()); } </del> if let Some(local) = set_output_capture(None) { <del> write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()), backtrace); </del> <ins> write(&mut *local.lock().unwrap_or_else(|e| e.into_inner())); </ins> set_output_capture(Some(local)); } else if let Some(mut out) = panic_output() { <del> write(&mut out, backtrace); </del> <ins> write(&mut out); </ins> } }

# Explicitly disabling ICE dump export RUSTC_ICE=0 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-disabled.log 2>&1 <del> should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt | wc -l) should_be_empty_dot=$(ls -l ./rustc-ice-*.txt | wc -l) </del> <ins> should_be_empty_tmp=$(ls -l $TMPDIR/rustc-ice-*.txt 2>/dev/null | wc -l) should_be_empty_dot=$(ls -l ./rustc-ice-*.txt 2>/dev/null | wc -l) </ins> echo "#### ICE Dump content:" echo $content