diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-06-20 10:08:06 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-06-20 10:17:40 +1000 |
| commit | 19b7192c7266ddd6d3b6fb3b436458fb84682f9c (patch) | |
| tree | d42ea38c4a700f0e5674fbab114f72e435198478 /compiler/rustc_errors | |
| parent | 894f7a4ba6554d3797404bbf550d9919df060b97 (diff) | |
| download | rust-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.rs | 28 |
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 { |
