about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-20 14:07:04 +0200
committerGitHub <noreply@github.com>2024-06-20 14:07:04 +0200
commitf511f2b18d0c5c3d974786781c3b01429a73f356 (patch)
treeb549c9a7e2b76bde99efebe897bffe10707399b3 /compiler/rustc_errors/src
parentef2e8bfcbfb10d54b8b8a0cdbe509783c7db5023 (diff)
parent19b7192c7266ddd6d3b6fb3b436458fb84682f9c (diff)
downloadrust-f511f2b18d0c5c3d974786781c3b01429a73f356.tar.gz
rust-f511f2b18d0c5c3d974786781c3b01429a73f356.zip
Rollup merge of #126719 - nnethercote:fix-126521, r=oli-obk
Fix assertion failure for some `Expect` diagnostics.

In #120699 I moved some code dealing with `has_future_breakage` earlier in `emit_diagnostic`. Issue #126521 identified a case where that reordering was invalid (leading to an assertion failure) for some `Expect` diagnostics.

This commit partially undoes the change, by moving the handling of unstable `Expect` diagnostics earlier again. This makes `emit_diagnostic` a bit uglier, but is necessary to fix the problem.

Fixes #126521.

r? ``@oli-obk``
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/lib.rs28
1 files changed, 19 insertions, 9 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 83d5bbff0b0..620f56c01e8 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1437,6 +1437,24 @@ impl DiagCtxtInner {
 
     // Return value is only `Some` if the level is `Error` or `DelayedBug`.
     fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
+        match diagnostic.level {
+            Expect(expect_id) | ForceWarning(Some(expect_id)) => {
+                // The `LintExpectationId` can be stable or unstable depending on when it was
+                // created. Diagnostics created before the definition of `HirId`s are unstable and
+                // can not yet be stored. Instead, they are buffered until the `LintExpectationId`
+                // is replaced by a stable one by the `LintLevelsBuilder`.
+                if let LintExpectationId::Unstable { .. } = expect_id {
+                    // We don't call TRACK_DIAGNOSTIC because we wait for the
+                    // unstable ID to be updated, whereupon the diagnostic will be
+                    // passed into this method again.
+                    self.unstable_expect_diagnostics.push(diagnostic);
+                    return None;
+                }
+                // Continue through to the `Expect`/`ForceWarning` case below.
+            }
+            _ => {}
+        }
+
         if diagnostic.has_future_breakage() {
             // Future breakages aren't emitted if they're `Level::Allow`,
             // but they still need to be constructed and stashed below,
@@ -1512,16 +1530,8 @@ impl DiagCtxtInner {
                 return None;
             }
             Expect(expect_id) | ForceWarning(Some(expect_id)) => {
-                // Diagnostics created before the definition of `HirId`s are
-                // unstable and can not yet be stored. Instead, they are
-                // buffered until the `LintExpectationId` is replaced by a
-                // stable one by the `LintLevelsBuilder`.
                 if let LintExpectationId::Unstable { .. } = expect_id {
-                    // We don't call TRACK_DIAGNOSTIC because we wait for the
-                    // unstable ID to be updated, whereupon the diagnostic will
-                    // be passed into this method again.
-                    self.unstable_expect_diagnostics.push(diagnostic);
-                    return None;
+                    unreachable!(); // this case was handled at the top of this function
                 }
                 self.fulfilled_expectations.insert(expect_id.normalize());
                 if let Expect(_) = diagnostic.level {