diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b8dda9ed5743..876a5340d93e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -2049,22 +2049,6 @@ pub fn elided_lifetime_in_path_suggestion( ElidedLifetimeInPathSubdiag { expected, indicate } } -pub fn report_ambiguity_error<'a, G: EmissionGuarantee>( - diag: &mut Diag<'a, G>, - ambiguity: rustc_lint_defs::AmbiguityErrorDiag, -) { - diag.span_label(ambiguity.label_span, ambiguity.label_msg); - diag.note(ambiguity.note_msg); - diag.span_note(ambiguity.b1_span, ambiguity.b1_note_msg); - for help_msg in ambiguity.b1_help_msgs { - diag.help(help_msg); - } - diag.span_note(ambiguity.b2_span, ambiguity.b2_note_msg); - for help_msg in ambiguity.b2_help_msgs { - diag.help(help_msg); - } -} - /// Grammatical tool for displaying messages to end users in a nice form. /// /// Returns "an" if the given string starts with a vowel, and "a" otherwise. diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 34bb3989008e..e376d7d2ab88 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -251,9 +251,6 @@ pub fn decorate_builtin_lint( } .decorate_lint(diag); } - BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => { - lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag); - } BuiltinLintDiag::AmbiguousGlobReexports { name, namespace, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 43786db8bdce..0687490645d3 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -15,7 +15,6 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; -use rustc_session::lint::AmbiguityErrorDiag; use rustc_span::edition::Edition; use rustc_span::{Ident, Span, Symbol, sym}; @@ -2836,18 +2835,6 @@ pub(crate) struct NamedArgumentUsedPositionally { pub named_arg_name: String, } -// FIXME: make this translatable -pub(crate) struct AmbiguousGlobImports { - pub ambiguity: AmbiguityErrorDiag, -} - -impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { - fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { - diag.primary_message(self.ambiguity.msg.clone()); - rustc_errors::report_ambiguity_error(diag, self.ambiguity); - } -} - #[derive(LintDiagnostic)] #[diag(lint_ambiguous_glob_reexport)] pub(crate) struct AmbiguousGlobReexports { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 8acb5eb31991..326fdaf9cec9 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -593,21 +593,6 @@ impl StableCompare for LintId { } } -#[derive(Debug)] -pub struct AmbiguityErrorDiag { - pub msg: String, - pub span: Span, - pub label_span: Span, - pub label_msg: String, - pub note_msg: String, - pub b1_span: Span, - pub b1_note_msg: String, - pub b1_help_msgs: Vec, - pub b2_span: Span, - pub b2_note_msg: String, - pub b2_help_msgs: Vec, -} - #[derive(Debug, Clone)] pub enum DeprecatedSinceKind { InEffect, @@ -678,9 +663,6 @@ pub enum BuiltinLintDiag { /// Indicates if the named argument is used as a width/precision for formatting is_formatting_arg: bool, }, - AmbiguousGlobImports { - diag: AmbiguityErrorDiag, - }, AmbiguousGlobReexports { /// The name for which collision(s) have occurred. name: String, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index fe299a6cebca..f6219808945e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -11,7 +11,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, MultiSpan, SuggestionStyle, - report_ambiguity_error, struct_span_code_err, + struct_span_code_err, }; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem}; @@ -22,16 +22,16 @@ use rustc_hir::{PrimTy, Stability, StabilityLevel, find_attr}; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::Session; +use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, }; -use rustc_session::lint::{AmbiguityErrorDiag, BuiltinLintDiag}; use rustc_session::utils::was_invoked_from_cargo; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; -use rustc_span::source_map::SourceMap; +use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::{BytePos, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, instrument}; @@ -145,7 +145,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } for ambiguity_error in &self.ambiguity_errors { - let diag = self.ambiguity_diagnostics(ambiguity_error); + let diag = self.ambiguity_diagnostic(ambiguity_error); + if ambiguity_error.warning { let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else { unreachable!() @@ -153,13 +154,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.lint_buffer.buffer_lint( AMBIGUOUS_GLOB_IMPORTS, import.root_id, - ambiguity_error.ident.span, - BuiltinLintDiag::AmbiguousGlobImports { diag }, + diag.ident.span, + diag, ); } else { - let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", diag.msg); - report_ambiguity_error(&mut err, diag); - err.emit(); + self.dcx().emit_err(diag); } } @@ -1995,7 +1994,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - fn ambiguity_diagnostics(&self, ambiguity_error: &AmbiguityError<'ra>) -> AmbiguityErrorDiag { + fn ambiguity_diagnostic(&self, ambiguity_error: &AmbiguityError<'ra>) -> errors::Ambiguity { let AmbiguityError { kind, ident, b1, b2, misc1, misc2, .. } = *ambiguity_error; let extern_prelude_ambiguity = || { self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)).is_some_and(|entry| { @@ -2038,8 +2037,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } ( - b.span, - note_msg, + Spanned { node: note_msg, span: b.span }, help_msgs .iter() .enumerate() @@ -2050,20 +2048,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .collect::>(), ) }; - let (b1_span, b1_note_msg, b1_help_msgs) = could_refer_to(b1, misc1, ""); - let (b2_span, b2_note_msg, b2_help_msgs) = could_refer_to(b2, misc2, " also"); + let (b1_note, b1_help_msgs) = could_refer_to(b1, misc1, ""); + let (b2_note, b2_help_msgs) = could_refer_to(b2, misc2, " also"); - AmbiguityErrorDiag { - msg: format!("`{ident}` is ambiguous"), - span: ident.span, - label_span: ident.span, - label_msg: "ambiguous name".to_string(), - note_msg: format!("ambiguous because of {}", kind.descr()), - b1_span, - b1_note_msg, + errors::Ambiguity { + ident, + kind: kind.descr(), + b1_note, b1_help_msgs, - b2_span, - b2_note_msg, + b2_note, b2_help_msgs, } } diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index fe1f0d253a12..af58d88ec35f 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1,9 +1,10 @@ use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, DiagMessage, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, - LintDiagnostic, MultiSpan, Subdiagnostic, + Applicability, Diag, DiagCtxtHandle, DiagMessage, Diagnostic, ElidedLifetimeInPathSubdiag, + EmissionGuarantee, IntoDiagArg, Level, LintDiagnostic, MultiSpan, Subdiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span, Symbol}; use crate::late::PatternSource; @@ -1445,3 +1446,43 @@ pub(crate) struct UnknownDiagnosticAttributeTypoSugg { pub span: Span, pub typo_name: Symbol, } + +// FIXME: Make this properly translatable. +pub(crate) struct Ambiguity { + pub ident: Ident, + pub kind: &'static str, + pub b1_note: Spanned, + pub b1_help_msgs: Vec, + pub b2_note: Spanned, + pub b2_help_msgs: Vec, +} + +impl Ambiguity { + fn decorate<'a>(self, diag: &mut Diag<'a, impl EmissionGuarantee>) { + diag.primary_message(format!("`{}` is ambiguous", self.ident)); + diag.span_label(self.ident.span, "ambiguous name"); + diag.note(format!("ambiguous because of {}", self.kind)); + diag.span_note(self.b1_note.span, self.b1_note.node); + for help_msg in self.b1_help_msgs { + diag.help(help_msg); + } + diag.span_note(self.b2_note.span, self.b2_note.node); + for help_msg in self.b2_help_msgs { + diag.help(help_msg); + } + } +} + +impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for Ambiguity { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { + let mut diag = Diag::new(dcx, level, "").with_span(self.ident.span).with_code(E0659); + self.decorate(&mut diag); + diag + } +} + +impl<'a> LintDiagnostic<'a, ()> for Ambiguity { + fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { + self.decorate(diag); + } +}