Change:
<!-- [31mICE[0m: Rustc '-Zunstable-options --edition=2024 -ooutputfile -Zdump-mir-dir=dir' 'thread 'rustc' panicked at 'assertion failed: matches!(, Error Allow)'' File: --auto-reduced (treereduce-rust): &lt;details&lt;summary&lt;strongoriginal code&lt;/strong&lt;/summary&lt;poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [earlylintchecks] perform lints prior to macro expansion [hircrate] getting the crate HIR -- label +F-stmtexpr_attributes
bisects to :thinking: cc edit: ah the assertion was there...

Discussion:
// Return value is only `Some` if the level is `Error` or `DelayedBug`. fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option<ErrorGuaranteed> { <ins> 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. } _ => {} } </ins> 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,

return None; } Expect(expect_id) | ForceWarning(Some(expect_id)) => { <del> // 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`. </del> if let LintExpectationId::Unstable { .. } = expect_id { <del> // 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; </del> <ins> unreachable!(); // this case was handled at the top of this function </ins> } self.fulfilled_expectations.insert(expect_id.normalize()); if let Expect(_) = diagnostic.level {

<del> //@ known-bug: rust-lang/rust#126521 macro_rules! foo { ($val:ident) => { true; }; } fn main() { #[expect(semicolon_in_expressions_from_macros)] let _ = foo!(x); } </del>

<ins> macro_rules! foo { ($val:ident) => { true; }; } fn main() { #[expect(semicolon_in_expressions_from_macros)] //~^ ERROR the `#[expect]` attribute is an experimental feature let _ = foo!(x); } </ins>

<ins> 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`. </ins>