about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-05 19:53:20 +0100
committerGitHub <noreply@github.com>2024-03-05 19:53:20 +0100
commit1b30268e5b7e78613bcb2c491e0b82ff1bae8b43 (patch)
tree16c1e5211be73610e1adc8b4a12ddf0aa47b5ec5
parent9153451a912b08a84ce313fcdcdcbda2ab92a600 (diff)
parent9c963fc5bcc5915db1b3f01c60d08add08504968 (diff)
downloadrust-1b30268e5b7e78613bcb2c491e0b82ff1bae8b43.tar.gz
rust-1b30268e5b7e78613bcb2c491e0b82ff1bae8b43.zip
Rollup merge of #121658 - jieyouxu:ice-outdated-nightly, r=oli-obk
Hint user to update nightly on ICEs produced from outdated nightly

This is a conservative best-effort approach to detect a potentially outdated nightly; it will fallback to the regular ICE-reporting if any of the following cases are true:
- Channel is not nightly
- Version information is not available
- Version date is not parseable as a YYYY-MM-DD or is missing
- System time is at least 36 hours ahead of the user's nightly release datetime.
- Any internal features are used.

Note that I'm not sure how to make a test for this: I tested this manually by `CFG_VER_DATE="2020-02-02" ./x build library --stage 1`, and also changing the channel detection in `rustc_driver_impl` from `Some("nightly")` to `Some("nightly" | "dev")`, and then running `rustc +stage1 test.rs -Ztreat-err-as-bug=1` with a non-existent `test.rs`.

<img width="1145" alt="Screenshot 2024-02-27 at 01 12 28" src="https://github.com/rust-lang/rust/assets/39484203/eff6af2e-4b19-4a70-af57-cd739ecf0e84">

Closes #118832.
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml2
-rw-r--r--compiler/rustc_driver_impl/messages.ftl4
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs35
-rw-r--r--compiler/rustc_driver_impl/src/session_diagnostics.rs11
4 files changed, 47 insertions, 5 deletions
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 242aa06fe3e..fcc0afd3488 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 39462112dc2..1b69a6e2fbe 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 ab1e37e4ac2..85be97ea24f 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 2b31fdd77cc..62d0da62d2a 100644
--- a/compiler/rustc_driver_impl/src/session_diagnostics.rs
+++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs
@@ -47,6 +47,17 @@ pub(crate) struct IceBugReport<'a> {
 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> {
     pub version: &'a str,