From d2d17c60bd62c03b91f6ded31b34da90addf2fc0 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Sun, 22 Jun 2025 00:12:13 +0800 Subject: [PATCH] Add runtime check to avoid overwrite arg easily in diag and store and restore snapshot when set subdiag arg Signed-off-by: xizheyin --- .../rustc_borrowck/src/diagnostics/mod.rs | 8 ++++- compiler/rustc_builtin_macros/src/errors.rs | 1 + compiler/rustc_const_eval/src/errors.rs | 3 ++ compiler/rustc_errors/src/diagnostic.rs | 32 ++++++++++++++++++- compiler/rustc_hir_analysis/src/errors.rs | 1 + .../src/hir_ty_lowering/errors.rs | 1 + compiler/rustc_lint/src/levels.rs | 5 +-- compiler/rustc_lint/src/lifetime_syntax.rs | 4 +-- compiler/rustc_lint/src/lints.rs | 11 ++++--- .../src/diagnostics/subdiagnostic.rs | 30 ++++++++++++++--- .../rustc_metadata/src/dependency_format.rs | 2 +- compiler/rustc_metadata/src/errors.rs | 3 +- compiler/rustc_mir_build/src/errors.rs | 17 +++++++--- .../src/thir/pattern/check_match.rs | 7 ++-- .../src/lint_tail_expr_drop_order.rs | 4 +++ compiler/rustc_passes/messages.ftl | 2 +- compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_passes/src/errors.rs | 3 +- compiler/rustc_passes/src/liveness.rs | 1 + compiler/rustc_resolve/src/diagnostics.rs | 14 ++++---- compiler/rustc_resolve/src/errors.rs | 5 +-- .../src/errors/note_and_explain.rs | 2 ++ 22 files changed, 119 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 5e3f3ffa2ea85..10dede787806a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1254,8 +1254,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && !spans.is_empty() { let mut span: MultiSpan = spans.clone().into(); + err.arg("ty", param_ty.to_string()); + let msg = err.dcx.eagerly_translate_to_string( + fluent::borrowck_moved_a_fn_once_in_call_def, + err.args.iter(), + ); + err.remove_arg("ty"); for sp in spans { - span.push_span_label(sp, fluent::borrowck_moved_a_fn_once_in_call_def); + span.push_span_label(sp, msg.clone()); } span.push_span_label( fn_call_span, diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 3a2e96a5e5af4..ec98fffb9c411 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -672,6 +672,7 @@ impl Subdiagnostic for FormatUnusedArg { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.arg("named", self.named); let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg); + diag.remove_arg("named"); diag.span_label(self.span, msg); } } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 037cbf777e70b..4ea2d6f2ebbed 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -293,6 +293,9 @@ impl Subdiagnostic for FrameNote { span.push_span_label(self.span, fluent::const_eval_frame_note_last); } let msg = diag.eagerly_translate(fluent::const_eval_frame_note); + diag.remove_arg("times"); + diag.remove_arg("where_"); + diag.remove_arg("instance"); diag.span_note(span, msg); } } diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index a11f81b55bb84..8da7cdd935880 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -289,6 +289,9 @@ pub struct DiagInner { pub suggestions: Suggestions, pub args: DiagArgMap, + // This is used to store args and restore them after a subdiagnostic is rendered. + pub reserved_args: DiagArgMap, + /// This is not used for highlighting or rendering any error message. Rather, it can be used /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of /// `span` if there is one. Otherwise, it is `DUMMY_SP`. @@ -319,6 +322,7 @@ impl DiagInner { children: vec![], suggestions: Suggestions::Enabled(vec![]), args: Default::default(), + reserved_args: Default::default(), sort_span: DUMMY_SP, is_lint: None, long_ty_path: None, @@ -390,7 +394,27 @@ impl DiagInner { } pub(crate) fn arg(&mut self, name: impl Into, arg: impl IntoDiagArg) { - self.args.insert(name.into(), arg.into_diag_arg(&mut self.long_ty_path)); + let name = name.into(); + let value = arg.into_diag_arg(&mut self.long_ty_path); + // This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg. + debug_assert!( + !self.args.contains_key(&name) || self.args.get(&name) == Some(&value), + "arg {} already exists", + name + ); + self.args.insert(name, value); + } + + pub fn remove_arg(&mut self, name: &str) { + self.args.swap_remove(name); + } + + pub fn store_args(&mut self) { + self.reserved_args = self.args.clone(); + } + + pub fn restore_args(&mut self) { + self.args = std::mem::take(&mut self.reserved_args); } /// Fields used for Hash, and PartialEq trait. @@ -1423,6 +1447,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.downgrade_to_delayed_bug(); self.emit() } + + pub fn remove_arg(&mut self, name: &str) { + if let Some(diag) = self.diag.as_mut() { + diag.remove_arg(name); + } + } } /// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 318aaab50f4d4..c920e25ad3763 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -127,6 +127,7 @@ pub(crate) enum AssocItemNotFoundSugg<'a> { SimilarInOtherTrait { #[primary_span] span: Span, + trait_name: &'a str, assoc_kind: &'static str, suggested_name: Symbol, }, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 0e79a8918b050..f211137ddd6ae 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -309,6 +309,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // change the associated item. err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait { span: assoc_ident.span, + trait_name: &trait_name, assoc_kind: assoc_kind_str, suggested_name, }); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c52dbd892bf4a..c72f8571153a8 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -482,7 +482,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let name = lint_name.as_str(); let suggestion = RenamedLintSuggestion::WithoutSpan { replace }; let requested_level = RequestedLevel { level, lint_name }; - let lint = RenamedLintFromCommandLine { name, suggestion, requested_level }; + let lint = + RenamedLintFromCommandLine { name, replace, suggestion, requested_level }; self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint); } CheckLintNameResult::Removed(ref reason) => { @@ -824,7 +825,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { RenamedLintSuggestion::WithSpan { suggestion: sp, replace }; let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); - let lint = RenamedLint { name: name.as_str(), suggestion }; + let lint = RenamedLint { name: name.as_str(), replace, suggestion }; self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); } diff --git a/compiler/rustc_lint/src/lifetime_syntax.rs b/compiler/rustc_lint/src/lifetime_syntax.rs index 95b7b69bd5a7b..5465968e98473 100644 --- a/compiler/rustc_lint/src/lifetime_syntax.rs +++ b/compiler/rustc_lint/src/lifetime_syntax.rs @@ -422,12 +422,12 @@ fn build_mismatch_suggestion( lifetime_name: &str, infos: &[&Info<'_>], ) -> lints::MismatchedLifetimeSyntaxesSuggestion { - let lifetime_name = lifetime_name.to_owned(); + let lifetime_name_sugg = lifetime_name.to_owned(); let suggestions = infos.iter().map(|info| info.suggestion(&lifetime_name)).collect(); lints::MismatchedLifetimeSyntaxesSuggestion::Explicit { - lifetime_name, + lifetime_name_sugg, suggestions, tool_only: false, } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index abdf8e3853bfb..583bd30c1a5d7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1089,6 +1089,7 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { #[diag(lint_renamed_lint)] pub(crate) struct RenamedLint<'a> { pub name: &'a str, + pub replace: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, } @@ -1109,6 +1110,7 @@ pub(crate) enum RenamedLintSuggestion<'a> { #[diag(lint_renamed_lint)] pub(crate) struct RenamedLintFromCommandLine<'a> { pub name: &'a str, + pub replace: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, #[subdiagnostic] @@ -3227,7 +3229,7 @@ pub(crate) enum MismatchedLifetimeSyntaxesSuggestion { }, Explicit { - lifetime_name: String, + lifetime_name_sugg: String, suggestions: Vec<(Span, String)>, tool_only: bool, }, @@ -3281,13 +3283,12 @@ impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion { ); } - Explicit { lifetime_name, suggestions, tool_only } => { - diag.arg("lifetime_name", lifetime_name); - + Explicit { lifetime_name_sugg, suggestions, tool_only } => { + diag.arg("lifetime_name_sugg", lifetime_name_sugg); let msg = diag.eagerly_translate( fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit, ); - + diag.remove_arg("lifetime_name_sugg"); diag.multipart_suggestion_with_style( msg, suggestions, diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index bc9516b2e0c67..04fdada802494 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -220,7 +220,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { } /// Generates the code for a field with no attributes. - fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> TokenStream { + fn generate_field_arg(&mut self, binding_info: &BindingInfo<'_>) -> (TokenStream, TokenStream) { let diag = &self.parent.diag; let field = binding_info.ast(); @@ -230,12 +230,16 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let ident = field.ident.as_ref().unwrap(); let ident = format_ident!("{}", ident); // strip `r#` prefix, if present - quote! { + let args = quote! { #diag.arg( stringify!(#ident), #field_binding ); - } + }; + let remove_args = quote! { + #diag.remove_arg(stringify!(#ident)); + }; + (args, remove_args) } /// Generates the necessary code for all attributes on a field. @@ -600,8 +604,13 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { calls.extend(call); } - - let plain_args: TokenStream = self + let store_args = quote! { + #diag.store_args(); + }; + let restore_args = quote! { + #diag.restore_args(); + }; + let (plain_args, remove_args): (TokenStream, TokenStream) = self .variant .bindings() .iter() @@ -610,12 +619,23 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { .collect(); let formatting_init = &self.formatting_init; + + // For #[derive(Subdiagnostic)] + // + // - Store args of the main diagnostic for later restore. + // - add args of subdiagnostic. + // - Generate the calls, such as note, label, etc. + // - Remove the arguments for allowing Vec to be used. + // - Restore the arguments for allowing main and subdiagnostic share the same fields. Ok(quote! { #init #formatting_init #attr_args + #store_args #plain_args #calls + #remove_args + #restore_args }) } } diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index fcae33c73c9c0..1089c4ac71c6c 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -314,7 +314,7 @@ fn add_library( crate_name: tcx.crate_name(cnum), non_static_deps: unavailable_as_static .drain(..) - .map(|cnum| NonStaticCrateDep { crate_name: tcx.crate_name(cnum) }) + .map(|cnum| NonStaticCrateDep { crate_name_: tcx.crate_name(cnum) }) .collect(), rustc_driver_help: linking_to_rustc_driver.then_some(RustcDriverHelp), }); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 71da429017415..4a3b43167cfa4 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -45,7 +45,8 @@ pub struct CrateDepMultiple { #[derive(Subdiagnostic)] #[note(metadata_crate_dep_not_static)] pub struct NonStaticCrateDep { - pub crate_name: Symbol, + /// It's different from `crate_name` in main Diagnostic. + pub crate_name_: Symbol, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index ae09db5023527..23869878e068d 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -994,14 +994,15 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { pub(crate) uncovered: Uncovered, #[subdiagnostic] pub(crate) inform: Option, - #[label(mir_build_confused)] - pub(crate) interpreted_as_const: Option, #[subdiagnostic] - pub(crate) interpreted_as_const_sugg: Option, + pub(crate) interpreted_as_const: Option, + #[subdiagnostic] + pub(crate) interpreted_as_const_sugg: Option, #[subdiagnostic] pub(crate) adt_defined_here: Option>, #[note(mir_build_privately_uninhabited)] pub(crate) witness_1_is_privately_uninhabited: bool, + pub(crate) witness_1: String, #[note(mir_build_pattern_ty)] pub(crate) _p: (), pub(crate) pattern_ty: Ty<'tcx>, @@ -1016,6 +1017,14 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { #[note(mir_build_more_information)] pub(crate) struct Inform; +#[derive(Subdiagnostic)] +#[label(mir_build_confused)] +pub(crate) struct InterpretedAsConst { + #[primary_span] + pub(crate) span: Span, + pub(crate) variable: String, +} + pub(crate) struct AdtDefinedHere<'tcx> { pub(crate) adt_def_span: Span, pub(crate) ty: Ty<'tcx>, @@ -1046,7 +1055,7 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { applicability = "maybe-incorrect", style = "verbose" )] -pub(crate) struct InterpretedAsConst { +pub(crate) struct InterpretedAsConstSugg { #[primary_span] pub(crate) span: Span, pub(crate) variable: String, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 245bd866030c1..1b7866d79b777 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -685,8 +685,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let span = self.tcx.def_span(def_id); let variable = self.tcx.item_name(def_id).to_string(); // When we encounter a constant as the binding name, point at the `const` definition. - interpreted_as_const = Some(span); - interpreted_as_const_sugg = Some(InterpretedAsConst { span: pat.span, variable }); + interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() }); + interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable }); } else if let PatKind::Constant { .. } = unpeeled_pat.kind && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span) { @@ -738,6 +738,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { false }; + let witness_1 = cx.print_witness_pat(witnesses.get(0).unwrap()); + self.error = Err(self.tcx.dcx().emit_err(PatternNotCovered { span: pat.span, origin, @@ -746,6 +748,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { interpreted_as_const, interpreted_as_const_sugg, witness_1_is_privately_uninhabited, + witness_1, _p: (), pattern_ty, let_suggestion, diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 75f351f05c30e..1bd770a85260c 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -516,8 +516,12 @@ struct LocalLabel<'a> { /// A custom `Subdiagnostic` implementation so that the notes are delivered in a specific order impl Subdiagnostic for LocalLabel<'_> { fn add_to_diag(self, diag: &mut rustc_errors::Diag<'_, G>) { + // Becuase parent uses this field , we need to remove it delay before adding it. + diag.remove_arg("name"); diag.arg("name", self.name); + diag.remove_arg("is_generated_name"); diag.arg("is_generated_name", self.is_generated_name); + diag.remove_arg("is_dropped_first_edition_2024"); diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024); let msg = diag.eagerly_translate(crate::fluent_generated::mir_transform_tail_expr_local); diag.span_label(self.span, msg); diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index c1a2b3b29733f..7ae99229d2579 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -291,7 +291,7 @@ passes_duplicate_lang_item_crate_depends = .second_definition_path = second definition in `{$crate_name}` loaded from {$path} passes_enum_variant_same_name = - it is impossible to refer to the {$descr} `{$dead_name}` because it is shadowed by this enum variant with the same name + it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name passes_export_name = attribute should be applied to a free function, impl method or static diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 4257d8e8d16bd..fded00684d453 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1078,7 +1078,7 @@ impl<'tcx> DeadVisitor<'tcx> { maybe_enum.variants().iter().find(|i| i.name == dead_item.name) { Some(crate::errors::EnumVariantSameName { - descr: tcx.def_descr(dead_item.def_id.to_def_id()), + dead_descr: tcx.def_descr(dead_item.def_id.to_def_id()), dead_name: dead_item.name, variant_span: tcx.def_span(variant.def_id), }) diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 587d9170f067c..ca92ad5ae5cbc 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1509,7 +1509,7 @@ pub(crate) struct EnumVariantSameName<'tcx> { #[primary_span] pub variant_span: Span, pub dead_name: Symbol, - pub descr: &'tcx str, + pub dead_descr: &'tcx str, } #[derive(Subdiagnostic)] @@ -1707,6 +1707,7 @@ impl Subdiagnostic for UnusedVariableStringInterp { #[derive(LintDiagnostic)] #[diag(passes_unused_variable_try_ignore)] pub(crate) struct UnusedVarTryIgnore { + pub name: String, #[subdiagnostic] pub sugg: UnusedVarTryIgnoreSugg, } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 763d9fda80494..46280b31c17a8 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1743,6 +1743,7 @@ impl<'tcx> Liveness<'_, 'tcx> { .map(|(_, pat_span, _)| *pat_span) .collect::>(), errors::UnusedVarTryIgnore { + name: name.clone(), sugg: errors::UnusedVarTryIgnoreSugg { shorthands, non_shorthands, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9149974a61774..8bca350c8ba24 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -256,22 +256,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; let label = match new_binding.is_import_user_facing() { - true => errors::NameDefinedMultipleTimeLabel::Reimported { span, name }, - false => errors::NameDefinedMultipleTimeLabel::Redefined { span, name }, + true => errors::NameDefinedMultipleTimeLabel::Reimported { span }, + false => errors::NameDefinedMultipleTimeLabel::Redefined { span }, }; let old_binding_label = (!old_binding.span.is_dummy() && old_binding.span != span).then(|| { let span = self.tcx.sess.source_map().guess_head_span(old_binding.span); match old_binding.is_import_user_facing() { - true => errors::NameDefinedMultipleTimeOldBindingLabel::Import { - span, - name, - old_kind, - }, + true => { + errors::NameDefinedMultipleTimeOldBindingLabel::Import { span, old_kind } + } false => errors::NameDefinedMultipleTimeOldBindingLabel::Definition { span, - name, old_kind, }, } @@ -281,6 +278,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .dcx() .create_err(errors::NameDefinedMultipleTime { span, + name, descr: ns.descr(), container, label, diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 7fe74378b6748..6d3752c0c8345 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -978,6 +978,7 @@ pub(crate) struct VariableNotInAllPatterns { pub(crate) struct NameDefinedMultipleTime { #[primary_span] pub(crate) span: Span, + pub(crate) name: Symbol, pub(crate) descr: &'static str, pub(crate) container: &'static str, #[subdiagnostic] @@ -992,13 +993,11 @@ pub(crate) enum NameDefinedMultipleTimeLabel { Reimported { #[primary_span] span: Span, - name: Symbol, }, #[label(resolve_name_defined_multiple_time_redefined)] Redefined { #[primary_span] span: Span, - name: Symbol, }, } @@ -1008,14 +1007,12 @@ pub(crate) enum NameDefinedMultipleTimeOldBindingLabel { Import { #[primary_span] span: Span, - name: Symbol, old_kind: &'static str, }, #[label(resolve_name_defined_multiple_time_old_binding_definition)] Definition { #[primary_span] span: Span, - name: Symbol, old_kind: &'static str, }, } diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 84e7686fdd3fc..ec3c1ba4a4551 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -163,12 +163,14 @@ impl RegionExplanation<'_> { impl Subdiagnostic for RegionExplanation<'_> { fn add_to_diag(self, diag: &mut Diag<'_, G>) { + diag.store_args(); diag.arg("pref_kind", self.prefix); diag.arg("suff_kind", self.suffix); diag.arg("desc_kind", self.desc.kind); diag.arg("desc_arg", self.desc.arg); let msg = diag.eagerly_translate(fluent::trait_selection_region_explanation); + diag.restore_args(); if let Some(span) = self.desc.span { diag.span_note(span, msg); } else {