Skip to content

Commit 19b7192

Browse files
committed
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.
1 parent 894f7a4 commit 19b7192

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

compiler/rustc_errors/src/lib.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,24 @@ impl DiagCtxtInner {
14371437

14381438
// Return value is only `Some` if the level is `Error` or `DelayedBug`.
14391439
fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
1440+
match diagnostic.level {
1441+
Expect(expect_id) | ForceWarning(Some(expect_id)) => {
1442+
// The `LintExpectationId` can be stable or unstable depending on when it was
1443+
// created. Diagnostics created before the definition of `HirId`s are unstable and
1444+
// can not yet be stored. Instead, they are buffered until the `LintExpectationId`
1445+
// is replaced by a stable one by the `LintLevelsBuilder`.
1446+
if let LintExpectationId::Unstable { .. } = expect_id {
1447+
// We don't call TRACK_DIAGNOSTIC because we wait for the
1448+
// unstable ID to be updated, whereupon the diagnostic will be
1449+
// passed into this method again.
1450+
self.unstable_expect_diagnostics.push(diagnostic);
1451+
return None;
1452+
}
1453+
// Continue through to the `Expect`/`ForceWarning` case below.
1454+
}
1455+
_ => {}
1456+
}
1457+
14401458
if diagnostic.has_future_breakage() {
14411459
// Future breakages aren't emitted if they're `Level::Allow`,
14421460
// but they still need to be constructed and stashed below,
@@ -1512,16 +1530,8 @@ impl DiagCtxtInner {
15121530
return None;
15131531
}
15141532
Expect(expect_id) | ForceWarning(Some(expect_id)) => {
1515-
// Diagnostics created before the definition of `HirId`s are
1516-
// unstable and can not yet be stored. Instead, they are
1517-
// buffered until the `LintExpectationId` is replaced by a
1518-
// stable one by the `LintLevelsBuilder`.
15191533
if let LintExpectationId::Unstable { .. } = expect_id {
1520-
// We don't call TRACK_DIAGNOSTIC because we wait for the
1521-
// unstable ID to be updated, whereupon the diagnostic will
1522-
// be passed into this method again.
1523-
self.unstable_expect_diagnostics.push(diagnostic);
1524-
return None;
1534+
unreachable!(); // this case was handled at the top of this function
15251535
}
15261536
self.fulfilled_expectations.insert(expect_id.normalize());
15271537
if let Expect(_) = diagnostic.level {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@ known-bug: rust-lang/rust#126521
21
macro_rules! foo {
32
($val:ident) => {
43
true;
@@ -7,5 +6,6 @@ macro_rules! foo {
76

87
fn main() {
98
#[expect(semicolon_in_expressions_from_macros)]
9+
//~^ ERROR the `#[expect]` attribute is an experimental feature
1010
let _ = foo!(x);
1111
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0658]: the `#[expect]` attribute is an experimental feature
2+
--> $DIR/expect-future_breakage-crash-issue-126521.rs:8:5
3+
|
4+
LL | #[expect(semicolon_in_expressions_from_macros)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
8+
= help: add `#![feature(lint_reasons)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)