about summary refs log tree commit diff
path: root/compiler/rustc_errors/src/lib.rs
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-02-17 18:47:40 +0100
committerGitHub <noreply@github.com>2024-02-17 18:47:40 +0100
commit45d577370415c3b16770b0abdfae8ec106909348 (patch)
treeff14fc4eebce4f3088d381e76e7d6dfc07e07acb /compiler/rustc_errors/src/lib.rs
parent59972868e63a24034a5d8379c8ca4146a72b7373 (diff)
parentb80fc5d4e8ce95a00b14a50e8ee0561b64736480 (diff)
downloadrust-45d577370415c3b16770b0abdfae8ec106909348.tar.gz
rust-45d577370415c3b16770b0abdfae8ec106909348.zip
Rollup merge of #121085 - davidtwco:always-eager-diagnostics, r=nnethercote
errors: only eagerly translate subdiagnostics

Subdiagnostics don't need to be lazily translated, they can always be eagerly translated. Eager translation is slightly more complex as we need to have a `DiagCtxt` available to perform the translation, which involves slightly more threading of that context.

This slight increase in complexity should enable later simplifications - like passing `DiagCtxt` into `AddToDiagnostic` and moving Fluent messages into the diagnostic structs rather than having them in separate files (working on that was what led to this change).

r? ```@nnethercote```
Diffstat (limited to 'compiler/rustc_errors/src/lib.rs')
-rw-r--r--compiler/rustc_errors/src/lib.rs71
1 files changed, 53 insertions, 18 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index b9b257856e6..064ea8d7516 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -643,7 +643,8 @@ impl DiagCtxt {
         message: DiagnosticMessage,
         args: impl Iterator<Item = DiagnosticArg<'a>>,
     ) -> SubdiagnosticMessage {
-        SubdiagnosticMessage::Eager(Cow::from(self.eagerly_translate_to_string(message, args)))
+        let inner = self.inner.borrow();
+        inner.eagerly_translate(message, args)
     }
 
     /// Translate `message` eagerly with `args` to `String`.
@@ -653,8 +654,7 @@ impl DiagCtxt {
         args: impl Iterator<Item = DiagnosticArg<'a>>,
     ) -> String {
         let inner = self.inner.borrow();
-        let args = crate::translation::to_fluent_args(args);
-        inner.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string()
+        inner.eagerly_translate_to_string(message, args)
     }
 
     // This is here to not allow mutation of flags;
@@ -1464,6 +1464,25 @@ impl DiagCtxtInner {
             .or_else(|| self.delayed_bugs.get(0).map(|(_, guar)| guar).copied())
     }
 
+    /// Translate `message` eagerly with `args` to `SubdiagnosticMessage::Eager`.
+    pub fn eagerly_translate<'a>(
+        &self,
+        message: DiagnosticMessage,
+        args: impl Iterator<Item = DiagnosticArg<'a>>,
+    ) -> SubdiagnosticMessage {
+        SubdiagnosticMessage::Translated(Cow::from(self.eagerly_translate_to_string(message, args)))
+    }
+
+    /// Translate `message` eagerly with `args` to `String`.
+    pub fn eagerly_translate_to_string<'a>(
+        &self,
+        message: DiagnosticMessage,
+        args: impl Iterator<Item = DiagnosticArg<'a>>,
+    ) -> String {
+        let args = crate::translation::to_fluent_args(args);
+        self.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string()
+    }
+
     fn flush_delayed(&mut self) {
         if self.delayed_bugs.is_empty() {
             return;
@@ -1502,15 +1521,22 @@ impl DiagCtxtInner {
             }
 
             let mut bug =
-                if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
+                if backtrace || self.ice_file.is_none() { bug.decorate(self) } else { bug.inner };
 
             // "Undelay" the delayed bugs (into plain `Bug`s).
             if bug.level != DelayedBug {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
-                bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
+                let subdiag = InvalidFlushedDelayedDiagnosticLevel {
                     span: bug.span.primary_span().unwrap(),
                     level: bug.level,
+                };
+                // FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it
+                // just uses `DiagCtxtInner` functions.
+                subdiag.add_to_diagnostic_with(&mut bug, |diag, msg| {
+                    let args = diag.args();
+                    let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
+                    self.eagerly_translate(msg, args)
                 });
             }
             bug.level = Bug;
@@ -1545,25 +1571,35 @@ impl DelayedDiagnostic {
         DelayedDiagnostic { inner: diagnostic, note: backtrace }
     }
 
-    fn decorate(mut self) -> Diagnostic {
+    fn decorate(mut self, dcx: &DiagCtxtInner) -> Diagnostic {
+        // FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it
+        // just uses `DiagCtxtInner` functions.
+        let subdiag_with = |diag: &mut Diagnostic, msg| {
+            let args = diag.args();
+            let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
+            dcx.eagerly_translate(msg, args)
+        };
+
         match self.note.status() {
             BacktraceStatus::Captured => {
                 let inner = &self.inner;
-                self.inner.subdiagnostic(DelayedAtWithNewline {
+                let subdiag = DelayedAtWithNewline {
                     span: inner.span.primary_span().unwrap_or(DUMMY_SP),
                     emitted_at: inner.emitted_at.clone(),
                     note: self.note,
-                });
+                };
+                subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with);
             }
             // Avoid the needless newline when no backtrace has been captured,
             // the display impl should just be a single line.
             _ => {
                 let inner = &self.inner;
-                self.inner.subdiagnostic(DelayedAtWithoutNewline {
+                let subdiag = DelayedAtWithoutNewline {
                     span: inner.span.primary_span().unwrap_or(DUMMY_SP),
                     emitted_at: inner.emitted_at.clone(),
                     note: self.note,
-                });
+                };
+                subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with);
             }
         }
 
@@ -1709,15 +1745,15 @@ impl Level {
 }
 
 // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
-pub fn add_elided_lifetime_in_path_suggestion(
+pub fn add_elided_lifetime_in_path_suggestion<E: EmissionGuarantee>(
     source_map: &SourceMap,
-    diag: &mut Diagnostic,
+    diag: &mut DiagnosticBuilder<'_, E>,
     n: usize,
     path_span: Span,
     incl_angl_brckt: bool,
     insertion_span: Span,
 ) {
-    diag.subdiagnostic(ExpectedLifetimeParameter { span: path_span, count: n });
+    diag.subdiagnostic(diag.dcx, ExpectedLifetimeParameter { span: path_span, count: n });
     if !source_map.is_span_accessible(insertion_span) {
         // Do not try to suggest anything if generated by a proc-macro.
         return;
@@ -1726,11 +1762,10 @@ pub fn add_elided_lifetime_in_path_suggestion(
     let suggestion =
         if incl_angl_brckt { format!("<{anon_lts}>") } else { format!("{anon_lts}, ") };
 
-    diag.subdiagnostic(IndicateAnonymousLifetime {
-        span: insertion_span.shrink_to_hi(),
-        count: n,
-        suggestion,
-    });
+    diag.subdiagnostic(
+        diag.dcx,
+        IndicateAnonymousLifetime { span: insertion_span.shrink_to_hi(), count: n, suggestion },
+    );
 }
 
 pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(