@@ -625,19 +625,13 @@ impl Handler {
625625 /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing.
626626 pub fn stash_diagnostic ( & self , span : Span , key : StashKey , diag : Diagnostic ) {
627627 let mut inner = self . inner . borrow_mut ( ) ;
628- // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
629- // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
630- // See the PR for a discussion.
631- inner. stashed_diagnostics . insert ( ( span, key) , diag) ;
628+ inner. stash ( ( span, key) , diag) ;
632629 }
633630
634631 /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key.
635632 pub fn steal_diagnostic ( & self , span : Span , key : StashKey ) -> Option < DiagnosticBuilder < ' _ , ( ) > > {
636- self . inner
637- . borrow_mut ( )
638- . stashed_diagnostics
639- . remove ( & ( span, key) )
640- . map ( |diag| DiagnosticBuilder :: new_diagnostic ( self , diag) )
633+ let mut inner = self . inner . borrow_mut ( ) ;
634+ inner. steal ( ( span, key) ) . map ( |diag| DiagnosticBuilder :: new_diagnostic ( self , diag) )
641635 }
642636
643637 /// Emit all stashed diagnostics.
@@ -1105,13 +1099,31 @@ impl HandlerInner {
11051099
11061100 /// Emit all stashed diagnostics.
11071101 fn emit_stashed_diagnostics ( & mut self ) -> Option < ErrorGuaranteed > {
1102+ let has_errors = self . has_errors ( ) ;
11081103 let diags = self . stashed_diagnostics . drain ( ..) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
11091104 let mut reported = None ;
11101105 for mut diag in diags {
1106+ // Decrement the count tracking the stash; emitting will increment it.
11111107 if diag. is_error ( ) {
1112- reported = Some ( ErrorGuaranteed ( ( ) ) ) ;
1108+ if matches ! ( diag. level, Level :: Error { lint: true } ) {
1109+ self . lint_err_count -= 1 ;
1110+ } else {
1111+ self . err_count -= 1 ;
1112+ }
1113+ } else {
1114+ if diag. is_force_warn ( ) {
1115+ self . warn_count -= 1 ;
1116+ } else {
1117+ // Unless they're forced, don't flush stashed warnings when
1118+ // there are errors, to avoid causing warning overload. The
1119+ // stash would've been stolen already if it were important.
1120+ if has_errors {
1121+ continue ;
1122+ }
1123+ }
11131124 }
1114- self . emit_diagnostic ( & mut diag) ;
1125+ let reported_this = self . emit_diagnostic ( & mut diag) ;
1126+ reported = reported. or ( reported_this) ;
11151127 }
11161128 reported
11171129 }
@@ -1301,9 +1313,47 @@ impl HandlerInner {
13011313 }
13021314 }
13031315
1316+ fn stash ( & mut self , key : ( Span , StashKey ) , diagnostic : Diagnostic ) {
1317+ // Track the diagnostic for counts, but don't panic-if-treat-err-as-bug
1318+ // yet; that happens when we actually emit the diagnostic.
1319+ if diagnostic. is_error ( ) {
1320+ if matches ! ( diagnostic. level, Level :: Error { lint: true } ) {
1321+ self . lint_err_count += 1 ;
1322+ } else {
1323+ self . err_count += 1 ;
1324+ }
1325+ } else {
1326+ // Warnings are only automatically flushed if they're forced.
1327+ if diagnostic. is_force_warn ( ) {
1328+ self . warn_count += 1 ;
1329+ }
1330+ }
1331+
1332+ // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
1333+ // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key.
1334+ // See the PR for a discussion.
1335+ self . stashed_diagnostics . insert ( key, diagnostic) ;
1336+ }
1337+
1338+ fn steal ( & mut self , key : ( Span , StashKey ) ) -> Option < Diagnostic > {
1339+ let diagnostic = self . stashed_diagnostics . remove ( & key) ?;
1340+ if diagnostic. is_error ( ) {
1341+ if matches ! ( diagnostic. level, Level :: Error { lint: true } ) {
1342+ self . lint_err_count -= 1 ;
1343+ } else {
1344+ self . err_count -= 1 ;
1345+ }
1346+ } else {
1347+ if diagnostic. is_force_warn ( ) {
1348+ self . warn_count -= 1 ;
1349+ }
1350+ }
1351+ Some ( diagnostic)
1352+ }
1353+
13041354 #[ inline]
13051355 fn err_count ( & self ) -> usize {
1306- self . err_count + self . stashed_diagnostics . len ( )
1356+ self . err_count
13071357 }
13081358
13091359 fn has_errors ( & self ) -> bool {
0 commit comments