about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2023-12-18 17:02:37 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2023-12-19 09:52:19 +1100
commit9ed87336b07d26776470218e316e2df5bc9f4112 (patch)
treee4fe562566356c1a3952b19577081824e30a2f85 /compiler/rustc_errors/src
parentf5459201e0f4f751bc30d890107942774ebf68fb (diff)
downloadrust-9ed87336b07d26776470218e316e2df5bc9f4112.tar.gz
rust-9ed87336b07d26776470218e316e2df5bc9f4112.zip
Factor out common `emit_producing_guarantee` code.
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs64
1 files changed, 21 insertions, 43 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 1c83250e017..828560ec452 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -112,6 +112,22 @@ pub trait EmissionGuarantee: Sized {
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult;
 }
 
+impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
+    /// Most `emit_producing_guarantee` functions use this as a starting point.
+    fn emit_producing_nothing(&mut self) {
+        match self.inner.state {
+            // First `.emit()` call, the `&DiagCtxt` is still available.
+            DiagnosticBuilderState::Emittable(dcx) => {
+                self.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
+
+                dcx.emit_diagnostic_without_consuming(&mut self.inner.diagnostic);
+            }
+            // `.emit()` was previously called, disallowed from repeating it.
+            DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
+        }
+    }
+}
+
 impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
     /// Discard the guarantee `.emit()` would return, in favor of having the
     /// type `DiagnosticBuilder<'a, ()>`. This may be necessary whenever there
@@ -124,6 +140,7 @@ impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
 // FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
 impl EmissionGuarantee for ErrorGuaranteed {
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
+        // Contrast this with `emit_producing_nothing`.
         match db.inner.state {
             // First `.emit()` call, the `&DiagCtxt` is still available.
             DiagnosticBuilderState::Emittable(dcx) => {
@@ -165,16 +182,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
 // FIXME(eddyb) should there be a `Option<ErrorGuaranteed>` impl as well?
 impl EmissionGuarantee for () {
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
-        match db.inner.state {
-            // First `.emit()` call, the `&DiagCtxt` is still available.
-            DiagnosticBuilderState::Emittable(dcx) => {
-                db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
-
-                dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
-            }
-            // `.emit()` was previously called, disallowed from repeating it.
-            DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
-        }
+        db.emit_producing_nothing();
     }
 }
 
@@ -187,17 +195,7 @@ impl EmissionGuarantee for BugAbort {
     type EmitResult = !;
 
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
-        match db.inner.state {
-            // First `.emit()` call, the `&DiagCtxt` is still available.
-            DiagnosticBuilderState::Emittable(dcx) => {
-                db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
-
-                dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
-            }
-            // `.emit()` was previously called, disallowed from repeating it.
-            DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
-        }
-        // Then panic. No need to return the marker type.
+        db.emit_producing_nothing();
         panic::panic_any(ExplicitBug);
     }
 }
@@ -211,34 +209,14 @@ impl EmissionGuarantee for FatalAbort {
     type EmitResult = !;
 
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
-        match db.inner.state {
-            // First `.emit()` call, the `&DiagCtxt` is still available.
-            DiagnosticBuilderState::Emittable(dcx) => {
-                db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
-
-                dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
-            }
-            // `.emit()` was previously called, disallowed from repeating it.
-            DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
-        }
-        // Then fatally error, returning `!`
+        db.emit_producing_nothing();
         crate::FatalError.raise()
     }
 }
 
 impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
     fn emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self::EmitResult {
-        match db.inner.state {
-            // First `.emit()` call, the `&DiagCtxt` is still available.
-            DiagnosticBuilderState::Emittable(dcx) => {
-                db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation;
-
-                dcx.emit_diagnostic_without_consuming(&mut db.inner.diagnostic);
-            }
-            // `.emit()` was previously called, disallowed from repeating it.
-            DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
-        }
-        // Then fatally error..
+        db.emit_producing_nothing();
         rustc_span::fatal_error::FatalError
     }
 }