@@ -69,7 +69,7 @@ use rustc_macros::{Decodable, Encodable};
6969pub use rustc_span:: fatal_error:: { FatalError , FatalErrorMarker } ;
7070use rustc_span:: source_map:: SourceMap ;
7171pub use rustc_span:: ErrorGuaranteed ;
72- use rustc_span:: { AttrId , Loc , Span , DUMMY_SP } ;
72+ use rustc_span:: { Loc , Span , DUMMY_SP } ;
7373pub use snippet:: Style ;
7474// Used by external projects such as `rust-gpu`.
7575// See https://github.com/rust-lang/rust/pull/115393.
@@ -497,28 +497,18 @@ struct DiagCtxtInner {
497497
498498 future_breakage_diagnostics : Vec < DiagInner > ,
499499
500- /// The [`Self::unstable_expect_diagnostics`] should be empty when this struct is
501- /// dropped. However, it can have values if the compilation is stopped early
502- /// or is only partially executed. To avoid ICEs, like in rust#94953 we only
503- /// check if [`Self::unstable_expect_diagnostics`] is empty, if the expectation ids
504- /// have been converted.
505- check_unstable_expect_diagnostics : bool ,
506-
507- /// Expected [`DiagInner`][struct@diagnostic::DiagInner]s store a [`LintExpectationId`] as part
508- /// of the lint level. [`LintExpectationId`]s created early during the compilation
509- /// (before `HirId`s have been defined) are not stable and can therefore not be
510- /// stored on disk. This buffer stores these diagnostics until the ID has been
511- /// replaced by a stable [`LintExpectationId`]. The [`DiagInner`][struct@diagnostic::DiagInner]s
512- /// are submitted for storage and added to the list of fulfilled expectations.
513- unstable_expect_diagnostics : Vec < DiagInner > ,
514-
515500 /// expected diagnostic will have the level `Expect` which additionally
516501 /// carries the [`LintExpectationId`] of the expectation that can be
517502 /// marked as fulfilled. This is a collection of all [`LintExpectationId`]s
518503 /// that have been marked as fulfilled this way.
519504 ///
520505 /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html
521- fulfilled_expectations : FxHashSet < LintExpectationId > ,
506+ fulfilled_expectations : FxIndexSet < LintExpectationId > ,
507+
508+ /// Whether `fulfilled_expectations` has been stolen. This is used to ICE in case we emit
509+ /// an expectation diagnostic after stealing it, which means that expectation would not be
510+ /// correctly handled.
511+ stolen_fulfilled_expectations : bool ,
522512
523513 /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be
524514 /// stored along side the main panic backtrace.
@@ -605,13 +595,6 @@ impl Drop for DiagCtxtInner {
605595 ) ;
606596 }
607597 }
608-
609- if self . check_unstable_expect_diagnostics {
610- assert ! (
611- self . unstable_expect_diagnostics. is_empty( ) ,
612- "all diagnostics with unstable expectations should have been converted" ,
613- ) ;
614- }
615598 }
616599}
617600
@@ -740,9 +723,8 @@ impl DiagCtxt {
740723 emitted_diagnostics,
741724 stashed_diagnostics,
742725 future_breakage_diagnostics,
743- check_unstable_expect_diagnostics,
744- unstable_expect_diagnostics,
745726 fulfilled_expectations,
727+ stolen_fulfilled_expectations : _,
746728 ice_file : _,
747729 } = inner. deref_mut ( ) ;
748730
@@ -761,8 +743,6 @@ impl DiagCtxt {
761743 * emitted_diagnostics = Default :: default ( ) ;
762744 * stashed_diagnostics = Default :: default ( ) ;
763745 * future_breakage_diagnostics = Default :: default ( ) ;
764- * check_unstable_expect_diagnostics = false ;
765- * unstable_expect_diagnostics = Default :: default ( ) ;
766746 * fulfilled_expectations = Default :: default ( ) ;
767747 }
768748
@@ -1094,44 +1074,11 @@ impl<'a> DiagCtxtHandle<'a> {
10941074 inner. emitter . emit_unused_externs ( lint_level, unused_externs)
10951075 }
10961076
1097- pub fn update_unstable_expectation_id (
1098- & self ,
1099- unstable_to_stable : FxIndexMap < AttrId , LintExpectationId > ,
1100- ) {
1101- let mut inner = self . inner . borrow_mut ( ) ;
1102- let diags = std:: mem:: take ( & mut inner. unstable_expect_diagnostics ) ;
1103- inner. check_unstable_expect_diagnostics = true ;
1104-
1105- if !diags. is_empty ( ) {
1106- inner. suppressed_expected_diag = true ;
1107- for mut diag in diags. into_iter ( ) {
1108- diag. update_unstable_expectation_id ( & unstable_to_stable) ;
1109-
1110- // Here the diagnostic is given back to `emit_diagnostic` where it was first
1111- // intercepted. Now it should be processed as usual, since the unstable expectation
1112- // id is now stable.
1113- inner. emit_diagnostic ( diag, self . tainted_with_errors ) ;
1114- }
1115- }
1116-
1117- inner
1118- . stashed_diagnostics
1119- . values_mut ( )
1120- . for_each ( |( diag, _guar) | diag. update_unstable_expectation_id ( & unstable_to_stable) ) ;
1121- inner
1122- . future_breakage_diagnostics
1123- . iter_mut ( )
1124- . for_each ( |diag| diag. update_unstable_expectation_id ( & unstable_to_stable) ) ;
1125- }
1126-
11271077 /// This methods steals all [`LintExpectationId`]s that are stored inside
11281078 /// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled.
11291079 #[ must_use]
1130- pub fn steal_fulfilled_expectation_ids ( & self ) -> FxHashSet < LintExpectationId > {
1131- assert ! (
1132- self . inner. borrow( ) . unstable_expect_diagnostics. is_empty( ) ,
1133- "`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point" ,
1134- ) ;
1080+ pub fn steal_fulfilled_expectation_ids ( & self ) -> FxIndexSet < LintExpectationId > {
1081+ self . inner . borrow_mut ( ) . stolen_fulfilled_expectations = true ;
11351082 std:: mem:: take ( & mut self . inner . borrow_mut ( ) . fulfilled_expectations )
11361083 }
11371084
@@ -1440,9 +1387,8 @@ impl DiagCtxtInner {
14401387 emitted_diagnostics : Default :: default ( ) ,
14411388 stashed_diagnostics : Default :: default ( ) ,
14421389 future_breakage_diagnostics : Vec :: new ( ) ,
1443- check_unstable_expect_diagnostics : false ,
1444- unstable_expect_diagnostics : Vec :: new ( ) ,
14451390 fulfilled_expectations : Default :: default ( ) ,
1391+ stolen_fulfilled_expectations : false ,
14461392 ice_file : None ,
14471393 }
14481394 }
@@ -1471,24 +1417,6 @@ impl DiagCtxtInner {
14711417 mut diagnostic : DiagInner ,
14721418 taint : Option < & Cell < Option < ErrorGuaranteed > > > ,
14731419 ) -> Option < ErrorGuaranteed > {
1474- match diagnostic. level {
1475- Expect ( expect_id) | ForceWarning ( Some ( expect_id) ) => {
1476- // The `LintExpectationId` can be stable or unstable depending on when it was
1477- // created. Diagnostics created before the definition of `HirId`s are unstable and
1478- // can not yet be stored. Instead, they are buffered until the `LintExpectationId`
1479- // is replaced by a stable one by the `LintLevelsBuilder`.
1480- if let LintExpectationId :: Unstable { .. } = expect_id {
1481- // We don't call TRACK_DIAGNOSTIC because we wait for the
1482- // unstable ID to be updated, whereupon the diagnostic will be
1483- // passed into this method again.
1484- self . unstable_expect_diagnostics . push ( diagnostic) ;
1485- return None ;
1486- }
1487- // Continue through to the `Expect`/`ForceWarning` case below.
1488- }
1489- _ => { }
1490- }
1491-
14921420 if diagnostic. has_future_breakage ( ) {
14931421 // Future breakages aren't emitted if they're `Level::Allow` or
14941422 // `Level::Expect`, but they still need to be constructed and
@@ -1564,9 +1492,10 @@ impl DiagCtxtInner {
15641492 return None ;
15651493 }
15661494 Expect ( expect_id) | ForceWarning ( Some ( expect_id) ) => {
1567- if let LintExpectationId :: Unstable { .. } = expect_id {
1568- unreachable ! ( ) ; // this case was handled at the top of this function
1569- }
1495+ assert ! (
1496+ !self . stolen_fulfilled_expectations,
1497+ "Attempting to emit an expected diagnostic after `check_expectations`." ,
1498+ ) ;
15701499 self . fulfilled_expectations . insert ( expect_id) ;
15711500 if let Expect ( _) = diagnostic. level {
15721501 // Nothing emitted here for expected lints.
0 commit comments