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.
This commit is contained in:
parent
894f7a4ba6
commit
19b7192c72
3 changed files with 33 additions and 10 deletions
|
@ -1437,6 +1437,24 @@ impl DiagCtxtInner {
|
||||||
|
|
||||||
// Return value is only `Some` if the level is `Error` or `DelayedBug`.
|
// Return value is only `Some` if the level is `Error` or `DelayedBug`.
|
||||||
fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option<ErrorGuaranteed> {
|
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() {
|
if diagnostic.has_future_breakage() {
|
||||||
// Future breakages aren't emitted if they're `Level::Allow`,
|
// Future breakages aren't emitted if they're `Level::Allow`,
|
||||||
// but they still need to be constructed and stashed below,
|
// but they still need to be constructed and stashed below,
|
||||||
|
@ -1512,16 +1530,8 @@ impl DiagCtxtInner {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Expect(expect_id) | ForceWarning(Some(expect_id)) => {
|
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 {
|
if let LintExpectationId::Unstable { .. } = expect_id {
|
||||||
// We don't call TRACK_DIAGNOSTIC because we wait for the
|
unreachable!(); // this case was handled at the top of this function
|
||||||
// unstable ID to be updated, whereupon the diagnostic will
|
|
||||||
// be passed into this method again.
|
|
||||||
self.unstable_expect_diagnostics.push(diagnostic);
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
self.fulfilled_expectations.insert(expect_id.normalize());
|
self.fulfilled_expectations.insert(expect_id.normalize());
|
||||||
if let Expect(_) = diagnostic.level {
|
if let Expect(_) = diagnostic.level {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//@ known-bug: rust-lang/rust#126521
|
|
||||||
macro_rules! foo {
|
macro_rules! foo {
|
||||||
($val:ident) => {
|
($val:ident) => {
|
||||||
true;
|
true;
|
||||||
|
@ -7,5 +6,6 @@ macro_rules! foo {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[expect(semicolon_in_expressions_from_macros)]
|
#[expect(semicolon_in_expressions_from_macros)]
|
||||||
|
//~^ ERROR the `#[expect]` attribute is an experimental feature
|
||||||
let _ = foo!(x);
|
let _ = foo!(x);
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0658]: the `#[expect]` attribute is an experimental feature
|
||||||
|
--> $DIR/expect-future_breakage-crash-issue-126521.rs:8:5
|
||||||
|
|
|
||||||
|
LL | #[expect(semicolon_in_expressions_from_macros)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
|
||||||
|
= help: add `#![feature(lint_reasons)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Add table
Add a link
Reference in a new issue