@@ -1275,6 +1275,9 @@ impl DiagCtxtInner {
12751275            self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ; 
12761276        } 
12771277
1278+         // Note that because this comes before the `match` below, 
1279+         // `-Zeagerly-emit-delayed-bugs` continues to work even after we've 
1280+         // issued an error and stopped recording new delayed bugs. 
12781281        if  diagnostic. level  == DelayedBug  && self . flags . eagerly_emit_delayed_bugs  { 
12791282            diagnostic. level  = Error ; 
12801283        } 
@@ -1286,18 +1289,20 @@ impl DiagCtxtInner {
12861289                diagnostic. level  = Bug ; 
12871290            } 
12881291            DelayedBug  => { 
1289-                 // FIXME(eddyb) this should check for `has_errors` and stop pushing 
1290-                 // once *any* errors were emitted (and truncate `delayed_bugs` 
1291-                 // when an error is first emitted, also), but maybe there's a case 
1292-                 // in which that's not sound? otherwise this is really inefficient. 
1293-                 let  backtrace = std:: backtrace:: Backtrace :: capture ( ) ; 
1294-                 // This `unchecked_error_guaranteed` is valid. It is where the 
1295-                 // `ErrorGuaranteed` for delayed bugs originates. 
1296-                 #[ allow( deprecated) ]  
1297-                 let  guar = ErrorGuaranteed :: unchecked_error_guaranteed ( ) ; 
1298-                 self . delayed_bugs 
1299-                     . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic,  backtrace) ,  guar) ) ; 
1300-                 return  Some ( guar) ; 
1292+                 // If we have already emitted at least one error, we don't need 
1293+                 // to record the delayed bug, because it'll never be used. 
1294+                 return  if  let  Some ( guar)  = self . has_errors_or_lint_errors ( )  { 
1295+                     Some ( guar) 
1296+                 }  else  { 
1297+                     let  backtrace = std:: backtrace:: Backtrace :: capture ( ) ; 
1298+                     // This `unchecked_error_guaranteed` is valid. It is where the 
1299+                     // `ErrorGuaranteed` for delayed bugs originates. 
1300+                     #[ allow( deprecated) ]  
1301+                     let  guar = ErrorGuaranteed :: unchecked_error_guaranteed ( ) ; 
1302+                     self . delayed_bugs 
1303+                         . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic,  backtrace) ,  guar) ) ; 
1304+                     Some ( guar) 
1305+                 } ; 
13011306            } 
13021307            Warning  if  !self . flags . can_emit_warnings  => { 
13031308                if  diagnostic. has_future_breakage ( )  { 
@@ -1363,6 +1368,16 @@ impl DiagCtxtInner {
13631368            } 
13641369
13651370            if  is_error { 
1371+                 // If we have any delayed bugs recorded, we can discard them 
1372+                 // because they won't be used. (This should only occur if there 
1373+                 // have been no errors previously emitted, because we don't add 
1374+                 // new delayed bugs once the first error is emitted.) 
1375+                 if  !self . delayed_bugs . is_empty ( )  { 
1376+                     assert_eq ! ( self . lint_err_guars. len( )  + self . err_guars. len( ) ,  0 ) ; 
1377+                     self . delayed_bugs . clear ( ) ; 
1378+                     self . delayed_bugs . shrink_to_fit ( ) ; 
1379+                 } 
1380+ 
13661381                // This `unchecked_error_guaranteed` is valid. It is where the 
13671382                // `ErrorGuaranteed` for errors and lint errors originates. 
13681383                #[ allow( deprecated) ]  
0 commit comments