about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorDavid Wood <david.wood@huawei.com>2022-10-03 14:14:51 +0100
committerDavid Wood <david.wood@huawei.com>2022-10-10 14:20:16 +0100
commit540b203bf9fe05e572f1baa938317d4c10df3528 (patch)
treee392b42d3f75127fcb34a138b4b0e30f45f90953 /compiler/rustc_errors/src
parentb4ac26289f17a5779d4318fb63436d94aebbf5ea (diff)
downloadrust-540b203bf9fe05e572f1baa938317d4c10df3528.tar.gz
rust-540b203bf9fe05e572f1baa938317d4c10df3528.zip
errors: `DiagnosticMessage::Eager`
Add variant of `DiagnosticMessage` for eagerly translated messages
(messages in the target language which don't need translated by the
emitter during emission). Also adds `eager_subdiagnostic` function which
is intended to be invoked by the diagnostic derive for subdiagnostic
fields which are marked as needing eager translation.

Signed-off-by: David Wood <david.wood@huawei.com>
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs19
-rw-r--r--compiler/rustc_errors/src/lib.rs11
-rw-r--r--compiler/rustc_errors/src/translation.rs4
3 files changed, 32 insertions, 2 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 2a6dd6da415..3e0840caaa6 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -939,6 +939,23 @@ impl Diagnostic {
         self
     }
 
+    /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see
+    /// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
+    /// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
+    /// interpolated variables).
+    pub fn eager_subdiagnostic(
+        &mut self,
+        handler: &crate::Handler,
+        subdiagnostic: impl AddToDiagnostic,
+    ) -> &mut Self {
+        subdiagnostic.add_to_diagnostic_with(self, |diag, msg| {
+            let args = diag.args();
+            let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
+            handler.eagerly_translate(msg, args)
+        });
+        self
+    }
+
     pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
         self.span = sp.into();
         if let Some(span) = self.span.primary_span() {
@@ -994,7 +1011,7 @@ impl Diagnostic {
     /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by
     /// combining it with the primary message of the diagnostic (if translatable, otherwise it just
     /// passes the user's string along).
-    fn subdiagnostic_message_to_diagnostic_message(
+    pub(crate) fn subdiagnostic_message_to_diagnostic_message(
         &self,
         attr: impl Into<SubdiagnosticMessage>,
     ) -> DiagnosticMessage {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 94a493992e5..61c9abbb0d6 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -598,6 +598,17 @@ impl Handler {
         }
     }
 
+    /// Translate `message` eagerly with `args`.
+    pub fn eagerly_translate<'a>(
+        &self,
+        message: DiagnosticMessage,
+        args: impl Iterator<Item = DiagnosticArg<'a, 'static>>,
+    ) -> SubdiagnosticMessage {
+        let inner = self.inner.borrow();
+        let args = crate::translation::to_fluent_args(args);
+        SubdiagnosticMessage::Eager(inner.emitter.translate_message(&message, &args).to_string())
+    }
+
     // This is here to not allow mutation of flags;
     // as of this writing it's only used in tests in librustc_middle.
     pub fn can_emit_warnings(&self) -> bool {
diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs
index c2ec2526a4a..a7737b467b7 100644
--- a/compiler/rustc_errors/src/translation.rs
+++ b/compiler/rustc_errors/src/translation.rs
@@ -55,7 +55,9 @@ pub trait Translate {
     ) -> Cow<'_, str> {
         trace!(?message, ?args);
         let (identifier, attr) = match message {
-            DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
+            DiagnosticMessage::Str(msg) | DiagnosticMessage::Eager(msg) => {
+                return Cow::Borrowed(&msg);
+            }
             DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
         };