diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 242aa06fe3e3c..fcc0afd3488b0 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -50,7 +50,7 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" -time = { version = "0.3", default-features = false, features = ["alloc", "formatting"] } +time = { version = "0.3", default-features = false, features = ["alloc", "formatting", "parsing", "macros"] } tracing = { version = "0.1.35" } # tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl index 39462112dc287..1b69a6e2fbecc 100644 --- a/compiler/rustc_driver_impl/messages.ftl +++ b/compiler/rustc_driver_impl/messages.ftl @@ -1,6 +1,10 @@ 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_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly +driver_impl_ice_bug_report_outdated = + it seems that this compiler `{$version}` is outdated, a newer nightly should have been released in the mean time + .update = please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists + .url = if the problem still persists, we would appreciate a bug report: {$bug_report_url} driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden driver_impl_ice_flags = compiler flags: {$flags} diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index ab1e37e4ac221..85be97ea24fdf 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -58,7 +58,7 @@ use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, OnceLock}; use std::time::{Instant, SystemTime}; -use time::OffsetDateTime; +use time::{Date, OffsetDateTime, Time}; #[allow(unused_macros)] macro do_not_use_print($($t:tt)*) { @@ -1369,6 +1369,9 @@ pub fn install_ice_hook( using_internal_features } +const DATE_FORMAT: &[time::format_description::FormatItem<'static>] = + &time::macros::format_description!("[year]-[month]-[day]"); + /// Prints the ICE message, including query stack, but without backtrace. /// /// The message will point the user at `bug_report_url` to report the ICE. @@ -1397,10 +1400,34 @@ fn report_ice( dcx.emit_err(session_diagnostics::Ice); } - if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) { - dcx.emit_note(session_diagnostics::IceBugReportInternalFeature); + use time::ext::NumericalDuration; + + // Try to hint user to update nightly if applicable when reporting an ICE. + // Attempt to calculate when current version was released, and add 12 hours + // as buffer. If the current version's release timestamp is older than + // the system's current time + 24 hours + 12 hours buffer if we're on + // nightly. + if let Some("nightly") = option_env!("CFG_RELEASE_CHANNEL") + && let Some(version) = option_env!("CFG_VERSION") + && let Some(ver_date_str) = option_env!("CFG_VER_DATE") + && let Ok(ver_date) = Date::parse(&ver_date_str, DATE_FORMAT) + && let ver_datetime = OffsetDateTime::new_utc(ver_date, Time::MIDNIGHT) + && let system_datetime = OffsetDateTime::from(SystemTime::now()) + && system_datetime.checked_sub(36.hours()).is_some_and(|d| d > ver_datetime) + && !using_internal_features.load(std::sync::atomic::Ordering::Relaxed) + { + dcx.emit_note(session_diagnostics::IceBugReportOutdated { + version, + bug_report_url, + note_update: (), + note_url: (), + }); } else { - dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url }); + if using_internal_features.load(std::sync::atomic::Ordering::Relaxed) { + dcx.emit_note(session_diagnostics::IceBugReportInternalFeature); + } else { + dcx.emit_note(session_diagnostics::IceBugReport { bug_report_url }); + } } let version = util::version_str!().unwrap_or("unknown_version"); diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs index 2b31fdd77cca3..62d0da62d2a79 100644 --- a/compiler/rustc_driver_impl/src/session_diagnostics.rs +++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs @@ -46,6 +46,17 @@ pub(crate) struct IceBugReport<'a> { #[diag(driver_impl_ice_bug_report_internal_feature)] pub(crate) struct IceBugReportInternalFeature; +#[derive(Diagnostic)] +#[diag(driver_impl_ice_bug_report_outdated)] +pub(crate) struct IceBugReportOutdated<'a> { + pub version: &'a str, + pub bug_report_url: &'a str, + #[note(driver_impl_update)] + pub note_update: (), + #[note(driver_impl_url)] + pub note_url: (), +} + #[derive(Diagnostic)] #[diag(driver_impl_ice_version)] pub(crate) struct IceVersion<'a> {