From 01178849174bdff3e3e951827d9ea4884c23b758 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 21 Mar 2025 10:09:17 -0400 Subject: Move eager translation to a method on `Diag` This will allow us to eagerly translate messages on a top-level diagnostic, such as a `LintDiagnostic`. As a bonus, we can remove the awkward closure passed into Subdiagnostic and make better use of `Into`. --- compiler/rustc_errors/src/diagnostic.rs | 33 +++++++++++---------------- compiler/rustc_errors/src/diagnostic_impls.rs | 8 ++----- compiler/rustc_errors/src/lib.rs | 2 +- 3 files changed, 16 insertions(+), 27 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index bd13c413a4d..539ecfbb42e 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -181,22 +181,9 @@ where Self: Sized, { /// Add a subdiagnostic to an existing diagnostic. - fn add_to_diag(self, diag: &mut Diag<'_, G>) { - self.add_to_diag_with(diag, &|_, m| m); - } - - /// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used - /// (to optionally perform eager translation). - fn add_to_diag_with>( - self, - diag: &mut Diag<'_, G>, - f: &F, - ); + fn add_to_diag(self, diag: &mut Diag<'_, G>); } -pub trait SubdiagMessageOp = - Fn(&mut Diag<'_, G>, SubdiagMessage) -> SubdiagMessage; - /// Trait implemented by lint types. This should not be implemented manually. Instead, use /// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic]. #[rustc_diagnostic_item = "LintDiagnostic"] @@ -1227,15 +1214,21 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// interpolated variables). #[rustc_lint_diagnostics] pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self { - let dcx = self.dcx; - subdiagnostic.add_to_diag_with(self, &|diag, msg| { - let args = diag.args.iter(); - let msg = diag.subdiagnostic_message_to_diagnostic_message(msg); - dcx.eagerly_translate(msg, args) - }); + subdiagnostic.add_to_diag(self); self } + /// Fluent variables are not namespaced from each other, so when + /// `Diagnostic`s and `Subdiagnostic`s use the same variable name, + /// one value will clobber the other. Eagerly translating the + /// diagnostic uses the variables defined right then, before the + /// clobbering occurs. + pub fn eagerly_translate(&self, msg: impl Into) -> SubdiagMessage { + let args = self.args.iter(); + let msg = self.subdiagnostic_message_to_diagnostic_message(msg.into()); + self.dcx.eagerly_translate(msg, args) + } + with_fn! { with_span, /// Add a span. #[rustc_lint_diagnostics] diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index cb2e1769fa1..8b59ba9984c 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -19,7 +19,7 @@ use {rustc_ast as ast, rustc_hir as hir}; use crate::diagnostic::DiagLocation; use crate::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level, - SubdiagMessageOp, Subdiagnostic, fluent_generated as fluent, + Subdiagnostic, fluent_generated as fluent, }; pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display); @@ -384,11 +384,7 @@ pub struct SingleLabelManySpans { pub label: &'static str, } impl Subdiagnostic for SingleLabelManySpans { - fn add_to_diag_with>( - self, - diag: &mut Diag<'_, G>, - _: &F, - ) { + fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.span_labels(self.spans, self.label); } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 75bb0e8e7b4..c0c5dba4677 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -47,7 +47,7 @@ pub use codes::*; pub use diagnostic::{ BugAbort, Diag, DiagArg, DiagArgMap, DiagArgName, DiagArgValue, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee, FatalAbort, IntoDiagArg, LintDiagnostic, StringPart, Subdiag, - SubdiagMessageOp, Subdiagnostic, + Subdiagnostic, }; pub use diagnostic_impls::{ DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter, -- cgit 1.4.1-3-g733a5