@@ -712,33 +712,47 @@ impl DiagCtxt {
712712 /// Stashes a diagnostic for possible later improvement in a different,
713713 /// later stage of the compiler. Possible actions depend on the diagnostic
714714 /// level:
715+ /// - Level::Bug, Level:Fatal: not allowed, will trigger a panic.
715716 /// - Level::Error: immediately counted as an error that has occurred, because it
716717 /// is guaranteed to be emitted eventually. Can be later accessed with the
717718 /// provided `span` and `key` through
718719 /// [`DiagCtxt::try_steal_modify_and_emit_err`] or
719720 /// [`DiagCtxt::try_steal_replace_and_emit_err`]. These do not allow
720721 /// cancellation or downgrading of the error. Returns
721722 /// `Some(ErrorGuaranteed)`.
723+ /// - Level::DelayedBug: this does happen occasionally with errors that are
724+ /// downgraded to delayed bugs. It is not stashed, but immediately
725+ /// emitted as a delayed bug. This is because stashing it would cause it
726+ /// to be counted by `err_count` which we don't want. It doesn't matter
727+ /// that we cannot steal and improve it later, because it's not a
728+ /// user-facing error. Returns `Some(ErrorGuaranteed)` as is normal for
729+ /// delayed bugs.
722730 /// - Level::Warning and lower (i.e. !is_error()): can be accessed with the
723731 /// provided `span` and `key` through [`DiagCtxt::steal_non_err()`]. This
724732 /// allows cancelling and downgrading of the diagnostic. Returns `None`.
725- /// - Others: not allowed, will trigger a panic.
726733 pub fn stash_diagnostic (
727734 & self ,
728735 span : Span ,
729736 key : StashKey ,
730737 diag : DiagInner ,
731738 ) -> Option < ErrorGuaranteed > {
732- let guar = if diag. level ( ) == Level :: Error {
733- // This `unchecked_error_guaranteed` is valid. It is where the
734- // `ErrorGuaranteed` for stashed errors originates. See
735- // `DiagCtxtInner::drop`.
736- #[ allow( deprecated) ]
737- Some ( ErrorGuaranteed :: unchecked_error_guaranteed ( ) )
738- } else if !diag. is_error ( ) {
739- None
740- } else {
741- self . span_bug ( span, format ! ( "invalid level in `stash_diagnostic`: {}" , diag. level) ) ;
739+ let guar = match diag. level {
740+ Bug | Fatal => {
741+ self . span_bug (
742+ span,
743+ format ! ( "invalid level in `stash_diagnostic`: {:?}" , diag. level) ,
744+ ) ;
745+ }
746+ Error => {
747+ // This `unchecked_error_guaranteed` is valid. It is where the
748+ // `ErrorGuaranteed` for stashed errors originates. See
749+ // `DiagCtxtInner::drop`.
750+ #[ allow( deprecated) ]
751+ Some ( ErrorGuaranteed :: unchecked_error_guaranteed ( ) )
752+ }
753+ DelayedBug => return self . inner . borrow_mut ( ) . emit_diagnostic ( diag) ,
754+ ForceWarning ( _) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
755+ | Expect ( _) => None ,
742756 } ;
743757
744758 // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
@@ -780,11 +794,11 @@ impl DiagCtxt {
780794 let err = self . inner . borrow_mut ( ) . stashed_diagnostics . swap_remove ( & key) ;
781795 err. map ( |( err, guar) | {
782796 // The use of `::<ErrorGuaranteed>` is safe because level is `Level::Error`.
783- assert_eq ! ( err. level, Level :: Error ) ;
797+ assert_eq ! ( err. level, Error ) ;
784798 assert ! ( guar. is_some( ) ) ;
785799 let mut err = Diag :: < ErrorGuaranteed > :: new_diagnostic ( self , err) ;
786800 modify_err ( & mut err) ;
787- assert_eq ! ( err. level, Level :: Error ) ;
801+ assert_eq ! ( err. level, Error ) ;
788802 err. emit ( )
789803 } )
790804 }
@@ -803,7 +817,7 @@ impl DiagCtxt {
803817 let old_err = self . inner . borrow_mut ( ) . stashed_diagnostics . swap_remove ( & key) ;
804818 match old_err {
805819 Some ( ( old_err, guar) ) => {
806- assert_eq ! ( old_err. level, Level :: Error ) ;
820+ assert_eq ! ( old_err. level, Error ) ;
807821 assert ! ( guar. is_some( ) ) ;
808822 // Because `old_err` has already been counted, it can only be
809823 // safely cancelled because the `new_err` supplants it.
@@ -1367,7 +1381,7 @@ impl DiagCtxtInner {
13671381 }
13681382
13691383 if diagnostic. has_future_breakage ( ) {
1370- // Future breakages aren't emitted if they're Level::Allow,
1384+ // Future breakages aren't emitted if they're ` Level::Allow` ,
13711385 // but they still need to be constructed and stashed below,
13721386 // so they'll trigger the must_produce_diag check.
13731387 self . suppressed_expected_diag = true ;
@@ -1453,7 +1467,7 @@ impl DiagCtxtInner {
14531467 diagnostic. children . extract_if ( already_emitted_sub) . for_each ( |_| { } ) ;
14541468 if already_emitted {
14551469 let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`" ;
1456- diagnostic. sub ( Level :: Note , msg, MultiSpan :: new ( ) ) ;
1470+ diagnostic. sub ( Note , msg, MultiSpan :: new ( ) ) ;
14571471 }
14581472
14591473 if is_error {
@@ -1623,7 +1637,7 @@ impl DiagCtxtInner {
16231637 bug. arg ( "level" , bug. level ) ;
16241638 let msg = crate :: fluent_generated:: errors_invalid_flushed_delayed_diagnostic_level;
16251639 let msg = self . eagerly_translate_for_subdiag ( & bug, msg) ; // after the `arg` call
1626- bug. sub ( Level :: Note , msg, bug. span . primary_span ( ) . unwrap ( ) . into ( ) ) ;
1640+ bug. sub ( Note , msg, bug. span . primary_span ( ) . unwrap ( ) . into ( ) ) ;
16271641 }
16281642 bug. level = Bug ;
16291643
@@ -1671,7 +1685,7 @@ impl DelayedDiagInner {
16711685 diag. arg ( "emitted_at" , diag. emitted_at . clone ( ) ) ;
16721686 diag. arg ( "note" , self . note ) ;
16731687 let msg = dcx. eagerly_translate_for_subdiag ( & diag, msg) ; // after the `arg` calls
1674- diag. sub ( Level :: Note , msg, diag. span . primary_span ( ) . unwrap_or ( DUMMY_SP ) . into ( ) ) ;
1688+ diag. sub ( Note , msg, diag. span . primary_span ( ) . unwrap_or ( DUMMY_SP ) . into ( ) ) ;
16751689 diag
16761690 }
16771691}
0 commit comments