about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-14 12:04:03 +0000
committerbors <bors@rust-lang.org>2024-02-14 12:04:03 +0000
commit340bb19fea20fd5f9357bbfac542fad84fc7ea2b (patch)
tree034e510c662af95a34913601c4988e262acbcd11 /compiler/rustc_errors/src
parent81b757c670483604c5ad04370bc505ba3d21356a (diff)
parent96635da9827020839b8949050c90458ea0d4c912 (diff)
downloadrust-340bb19fea20fd5f9357bbfac542fad84fc7ea2b.tar.gz
rust-340bb19fea20fd5f9357bbfac542fad84fc7ea2b.zip
Auto merge of #121078 - oli-obk:rollup-p11zsav, r=oli-obk
Rollup of 13 pull requests

Successful merges:

 - #116387 (Additional doc links and explanation of `Wake`.)
 - #118738 (Netbsd10 update)
 - #118890 (Clarify the lifetimes of allocations returned by the `Allocator` trait)
 - #120498 (Uplift `TypeVisitableExt` into `rustc_type_ir`)
 - #120530 (Be less confident when `dyn` suggestion is not checked for object safety)
 - #120915 (Fix suggestion span for `?Sized` when param type has default)
 - #121015 (Optimize `delayed_bug` handling.)
 - #121024 (implement `Default` for `AsciiChar`)
 - #121039 (Correctly compute adjustment casts in GVN)
 - #121045 (Fix two UI tests with incorrect directive / invalid revision)
 - #121049 (Do not point at `#[allow(_)]` as the reason for compat lint triggering)
 - #121071 (Use fewer delayed bugs.)
 - #121073 (Fix typos in `OneLock` doc)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/lib.rs39
1 files changed, 27 insertions, 12 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index b738ecb54ff..d876f28040d 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
+        // Note that because this comes before the `match` below,
+        // `-Zeagerly-emit-delayed-bugs` continues to work even after we've
+        // issued an error and stopped recording new delayed bugs.
         if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
             diagnostic.level = Error;
         }
@@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
                 diagnostic.level = Bug;
             }
             DelayedBug => {
-                // FIXME(eddyb) this should check for `has_errors` and stop pushing
-                // once *any* errors were emitted (and truncate `delayed_bugs`
-                // when an error is first emitted, also), but maybe there's a case
-                // in which that's not sound? otherwise this is really inefficient.
-                let backtrace = std::backtrace::Backtrace::capture();
-                // This `unchecked_error_guaranteed` is valid. It is where the
-                // `ErrorGuaranteed` for delayed bugs originates.
-                #[allow(deprecated)]
-                let guar = ErrorGuaranteed::unchecked_error_guaranteed();
-                self.delayed_bugs
-                    .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
-                return Some(guar);
+                // If we have already emitted at least one error, we don't need
+                // to record the delayed bug, because it'll never be used.
+                return if let Some(guar) = self.has_errors_or_lint_errors() {
+                    Some(guar)
+                } else {
+                    let backtrace = std::backtrace::Backtrace::capture();
+                    // This `unchecked_error_guaranteed` is valid. It is where the
+                    // `ErrorGuaranteed` for delayed bugs originates.
+                    #[allow(deprecated)]
+                    let guar = ErrorGuaranteed::unchecked_error_guaranteed();
+                    self.delayed_bugs
+                        .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
+                    Some(guar)
+                };
             }
             Warning if !self.flags.can_emit_warnings => {
                 if diagnostic.has_future_breakage() {
@@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
             }
 
             if is_error {
+                // If we have any delayed bugs recorded, we can discard them
+                // because they won't be used. (This should only occur if there
+                // have been no errors previously emitted, because we don't add
+                // new delayed bugs once the first error is emitted.)
+                if !self.delayed_bugs.is_empty() {
+                    assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
+                    self.delayed_bugs.clear();
+                    self.delayed_bugs.shrink_to_fit();
+                }
+
                 // This `unchecked_error_guaranteed` is valid. It is where the
                 // `ErrorGuaranteed` for errors and lint errors originates.
                 #[allow(deprecated)]