@@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
13151315 self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
13161316 }
13171317
1318+ // Note that because this comes before the `match` below,
1319+ // `-Zeagerly-emit-delayed-bugs` continues to work even after we've
1320+ // issued an error and stopped recording new delayed bugs.
13181321 if diagnostic. level == DelayedBug && self . flags . eagerly_emit_delayed_bugs {
13191322 diagnostic. level = Error ;
13201323 }
@@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
13261329 diagnostic. level = Bug ;
13271330 }
13281331 DelayedBug => {
1329- // FIXME(eddyb) this should check for `has_errors` and stop pushing
1330- // once *any* errors were emitted (and truncate `delayed_bugs`
1331- // when an error is first emitted, also), but maybe there's a case
1332- // in which that's not sound? otherwise this is really inefficient.
1333- let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1334- // This `unchecked_error_guaranteed` is valid. It is where the
1335- // `ErrorGuaranteed` for delayed bugs originates.
1336- #[ allow( deprecated) ]
1337- let guar = ErrorGuaranteed :: unchecked_error_guaranteed ( ) ;
1338- self . delayed_bugs
1339- . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) , guar) ) ;
1340- return Some ( guar) ;
1332+ // If we have already emitted at least one error, we don't need
1333+ // to record the delayed bug, because it'll never be used.
1334+ return if let Some ( guar) = self . has_errors_or_lint_errors ( ) {
1335+ Some ( guar)
1336+ } else {
1337+ let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1338+ // This `unchecked_error_guaranteed` is valid. It is where the
1339+ // `ErrorGuaranteed` for delayed bugs originates.
1340+ #[ allow( deprecated) ]
1341+ let guar = ErrorGuaranteed :: unchecked_error_guaranteed ( ) ;
1342+ self . delayed_bugs
1343+ . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) , guar) ) ;
1344+ Some ( guar)
1345+ } ;
13411346 }
13421347 Warning if !self . flags . can_emit_warnings => {
13431348 if diagnostic. has_future_breakage ( ) {
@@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
14031408 }
14041409
14051410 if is_error {
1411+ // If we have any delayed bugs recorded, we can discard them
1412+ // because they won't be used. (This should only occur if there
1413+ // have been no errors previously emitted, because we don't add
1414+ // new delayed bugs once the first error is emitted.)
1415+ if !self . delayed_bugs . is_empty ( ) {
1416+ assert_eq ! ( self . lint_err_guars. len( ) + self . err_guars. len( ) , 0 ) ;
1417+ self . delayed_bugs . clear ( ) ;
1418+ self . delayed_bugs . shrink_to_fit ( ) ;
1419+ }
1420+
14061421 // This `unchecked_error_guaranteed` is valid. It is where the
14071422 // `ErrorGuaranteed` for errors and lint errors originates.
14081423 #[ allow( deprecated) ]
0 commit comments