@@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
1315
1315
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1316
1316
}
1317
1317
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.
1318
1321
if diagnostic. level == DelayedBug && self . flags . eagerly_emit_delayed_bugs {
1319
1322
diagnostic. level = Error ;
1320
1323
}
@@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
1326
1329
diagnostic. level = Bug ;
1327
1330
}
1328
1331
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
+ } ;
1341
1346
}
1342
1347
Warning if !self . flags . can_emit_warnings => {
1343
1348
if diagnostic. has_future_breakage ( ) {
@@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
1403
1408
}
1404
1409
1405
1410
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
+
1406
1421
// This `unchecked_error_guaranteed` is valid. It is where the
1407
1422
// `ErrorGuaranteed` for errors and lint errors originates.
1408
1423
#[ allow( deprecated) ]
0 commit comments