about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-21 10:04:42 +0000
committerbors <bors@rust-lang.org>2022-08-21 10:04:42 +0000
commit4b695f7c4e1a02d160fe7e159abd0f87027c0fcf (patch)
tree2c7322f5189d638990acf9ad89b5cec9e3aeb6c0 /compiler/rustc_errors/src
parent39a9b88f4e50d4c0204bb12c0821b49a302ab3c5 (diff)
parent7f3a6fd7f6c04635f3d541201199f127f2a2e65e (diff)
downloadrust-4b695f7c4e1a02d160fe7e159abd0f87027c0fcf.tar.gz
rust-4b695f7c4e1a02d160fe7e159abd0f87027c0fcf.zip
Auto merge of #100765 - Xiretza:session-diagnostic-unification, r=compiler-errors
Kind-less SessionDiagnostic derive

From https://github.com/rust-lang/rust/pull/100730#discussion_r949712629:

> Hm, maybe we should expose some `sess.struct_$SOMETHING` (like `struct_diagnostic`?) that is generic over `EmissionGuarantee`, then make the `SessionDiagnostic` derive generic, i.e.
>
> ```rust
> impl<'tcx> SessionDiagnostic for UnusedGenericParams {
>   fn into_diagnostic<T: EmissionGuarantee>( .. ) -> DiagnosticBuilder<'tcx, T> {
>     let mut diag = sess.struct_diagnostic(rustc_errors:..);
>     ..
>   }
> }
> ```

Discussed [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/147480-t-compiler.2Fwg-diagnostics/topic/.23100717.20translation.20-.20kind-less.20derive).
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs30
-rw-r--r--compiler/rustc_errors/src/lib.rs9
2 files changed, 39 insertions, 0 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 04159bff4ff..61d767a1cc6 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -84,6 +84,13 @@ pub trait EmissionGuarantee: Sized {
     /// of `Self` without actually performing the emission.
     #[track_caller]
     fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self;
+
+    /// Creates a new `DiagnosticBuilder` that will return this type of guarantee.
+    #[track_caller]
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self>;
 }
 
 /// Private module for sealing the `IsError` helper trait.
@@ -166,6 +173,15 @@ impl EmissionGuarantee for ErrorGuaranteed {
             }
         }
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
+            handler, msg,
+        )
+    }
 }
 
 impl<'a> DiagnosticBuilder<'a, ()> {
@@ -208,6 +224,13 @@ impl EmissionGuarantee for () {
             DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {}
         }
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new(handler, Level::Warning(None), msg)
+    }
 }
 
 impl<'a> DiagnosticBuilder<'a, !> {
@@ -247,6 +270,13 @@ impl EmissionGuarantee for ! {
         // Then fatally error, returning `!`
         crate::FatalError.raise()
     }
+
+    fn make_diagnostic_builder(
+        handler: &Handler,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, Self> {
+        DiagnosticBuilder::new_fatal(handler, msg)
+    }
 }
 
 /// In general, the `DiagnosticBuilder` uses deref to allow access to
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 18e84b70b1b..9b9c334d4df 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -641,6 +641,15 @@ impl Handler {
         self.inner.borrow_mut().emit_stashed_diagnostics()
     }
 
+    /// Construct a builder with the `msg` at the level appropriate for the specific `EmissionGuarantee`.
+    #[rustc_lint_diagnostics]
+    pub fn struct_diagnostic<G: EmissionGuarantee>(
+        &self,
+        msg: impl Into<DiagnosticMessage>,
+    ) -> DiagnosticBuilder<'_, G> {
+        G::make_diagnostic_builder(self, msg)
+    }
+
     /// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
     ///
     /// Attempting to `.emit()` the builder will only emit if either: