@@ -1275,6 +1275,9 @@ impl DiagCtxtInner {
1275
1275
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1276
1276
}
1277
1277
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.
1278
1281
if diagnostic. level == DelayedBug && self . flags . eagerly_emit_delayed_bugs {
1279
1282
diagnostic. level = Error ;
1280
1283
}
@@ -1286,18 +1289,20 @@ impl DiagCtxtInner {
1286
1289
diagnostic. level = Bug ;
1287
1290
}
1288
1291
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
+ } ;
1301
1306
}
1302
1307
Warning if !self . flags . can_emit_warnings => {
1303
1308
if diagnostic. has_future_breakage ( ) {
@@ -1363,6 +1368,16 @@ impl DiagCtxtInner {
1363
1368
}
1364
1369
1365
1370
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
+
1366
1381
// This `unchecked_error_guaranteed` is valid. It is where the
1367
1382
// `ErrorGuaranteed` for errors and lint errors originates.
1368
1383
#[ allow( deprecated) ]
0 commit comments