about summary refs log tree commit diff
path: root/compiler/rustc_errors/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_errors/src/lib.rs')
-rw-r--r--compiler/rustc_errors/src/lib.rs56
1 files changed, 34 insertions, 22 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 136c15acb35..aefebfec448 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -519,7 +519,8 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
 pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> =
     AtomicRef::new(&(default_track_diagnostic as _));
 
-enum DelayedBugKind {
+#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
+pub enum DelayedBugKind {
     Normal,
     GoodPath,
 }
@@ -865,7 +866,8 @@ impl DiagCtxt {
         if treat_next_err_as_bug {
             self.bug(msg);
         }
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
+            .emit()
     }
 
     /// Like `delayed_bug`, but takes an additional span.
@@ -882,16 +884,15 @@ impl DiagCtxt {
         if treat_next_err_as_bug {
             self.span_bug(sp, msg);
         }
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
+            .with_span(sp)
+            .emit()
     }
 
     // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
     // where the explanation of what "good path" is (also, it should be renamed).
     pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
-        let mut inner = self.inner.borrow_mut();
-        let diagnostic = Diagnostic::new(DelayedBug, msg);
-        let backtrace = std::backtrace::Backtrace::capture();
-        inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+        DiagnosticBuilder::<()>::new(self, DelayedBug(DelayedBugKind::GoodPath), msg).emit()
     }
 
     #[track_caller]
@@ -1268,17 +1269,27 @@ impl DiagCtxtInner {
             return None;
         }
 
-        if diagnostic.level == DelayedBug {
-            // FIXME(eddyb) this should check for `has_errors` and stop pushing
-            // once *any* errors were emitted (and truncate `span_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();
-            self.span_delayed_bugs
-                .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
+        // FIXME(eddyb) this should check for `has_errors` and stop pushing
+        // once *any* errors were emitted (and truncate `span_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.
+        match diagnostic.level {
+            DelayedBug(DelayedBugKind::Normal) => {
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.span_delayed_bugs
+                    .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
 
-            #[allow(deprecated)]
-            return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+                #[allow(deprecated)]
+                return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+            }
+            DelayedBug(DelayedBugKind::GoodPath) => {
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.good_path_delayed_bugs
+                    .push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
+
+                return None;
+            }
+            _ => {}
         }
 
         if diagnostic.has_future_breakage() {
@@ -1438,7 +1449,7 @@ impl DiagCtxtInner {
                 if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
 
             // "Undelay" the `DelayedBug`s (into plain `Bug`s).
-            if bug.level != DelayedBug {
+            if !matches!(bug.level, DelayedBug(_)) {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
                 bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
@@ -1526,8 +1537,9 @@ pub enum Level {
     /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
     /// that should only be reached when compiling erroneous code.
     ///
-    /// Its `EmissionGuarantee` is `ErrorGuaranteed`.
-    DelayedBug,
+    /// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for
+    /// `GoodPath` delayed bugs.
+    DelayedBug(DelayedBugKind),
 
     /// An error that causes an immediate abort. Used for things like configuration errors,
     /// internal overflows, some file operation errors.
@@ -1602,7 +1614,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | DelayedBug | Fatal | Error => {
+            Bug | DelayedBug(_) | Fatal | Error => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
             ForceWarning(_) | Warning => {
@@ -1622,7 +1634,7 @@ impl Level {
 
     pub fn to_str(self) -> &'static str {
         match self {
-            Bug | DelayedBug => "error: internal compiler error",
+            Bug | DelayedBug(_) => "error: internal compiler error",
             Fatal | Error => "error",
             ForceWarning(_) | Warning => "warning",
             Note | OnceNote => "note",