Code change:
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.

Related discussion:
text: 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.