about summary refs log tree commit diff
path: root/compiler/rustc_errors
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2024-06-20 10:08:06 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2024-06-20 10:17:40 +1000
commit19b7192c7266ddd6d3b6fb3b436458fb84682f9c (patch)
treed42ea38c4a700f0e5674fbab114f72e435198478 /compiler/rustc_errors
parent894f7a4ba6554d3797404bbf550d9919df060b97 (diff)
downloadrust-19b7192c7266ddd6d3b6fb3b436458fb84682f9c.tar.gz
rust-19b7192c7266ddd6d3b6fb3b436458fb84682f9c.zip
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.
Diffstat (limited to 'compiler/rustc_errors')
-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 {