@@ -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