From 0609c0f1da13c8b0aeb90b5ff66f527bb16d58bf Mon Sep 17 00:00:00 2001 From: Nathan Stocks Date: Thu, 22 Sep 2022 18:23:05 -0600 Subject: [PATCH] migrate diagnostic_items.rs to translateable diagnostics --- .../locales/en-US/passes.ftl | 12 ++++++- compiler/rustc_passes/src/diagnostic_items.rs | 36 +++++++++---------- compiler/rustc_passes/src/errors.rs | 20 +++++++++++ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 49cd2ee17588..04fd0a3a6ac2 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -357,7 +357,7 @@ passes_collapse_debuginfo = passes_deprecated_annotation_has_no_effect = this `#[deprecated]` annotation has no effect .suggestion = remove the unnecessary deprecation attribute - + passes_unknown_external_lang_item = unknown external lang item: `{$lang_item}` @@ -389,3 +389,13 @@ passes_local_duplicate_lang_item = passes_invalid_attr_at_crate_level = `{$name}` attribute cannot be used at crate level .suggestion = perhaps you meant to use an outer attribute + +passes_duplicate_diagnostic_item = + duplicate diagnostic item found: `{$name}`. + +passes_duplicate_diagnostic_item_in_crate = + duplicate diagnostic item in crate `{$crate_name}`: `{$name}`. + +passes_diagnostic_item_first_defined = + the diagnostic item is first defined here + .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index e428d9293db1..c411a2471659 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -16,6 +16,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_span::symbol::{sym, Symbol}; +use crate::errors::{DuplicateDiagnosticItem, DuplicateDiagnosticItemInCrate}; + fn observe_item<'tcx>( tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, @@ -33,25 +35,23 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item items.id_to_name.insert(item_def_id, name); if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) { if original_def_id != item_def_id { - let mut err = match tcx.hir().span_if_local(item_def_id) { - Some(span) => tcx - .sess - .struct_span_err(span, &format!("duplicate diagnostic item found: `{name}`.")), - None => tcx.sess.struct_err(&format!( - "duplicate diagnostic item in crate `{}`: `{}`.", - tcx.crate_name(item_def_id.krate), - name - )), - }; - if let Some(span) = tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "the diagnostic item is first defined here"); + let orig_span = tcx.hir().span_if_local(original_def_id); + let orig_crate_name = if orig_span.is_some() { + None } else { - err.note(&format!( - "the diagnostic item is first defined in crate `{}`.", - tcx.crate_name(original_def_id.krate) - )); - } - err.emit(); + Some(tcx.crate_name(original_def_id.krate)) + }; + match tcx.hir().span_if_local(item_def_id) { + Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), + None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { + span: orig_span, + // FIXME: We should not provide `name` to `orig_crate_name`. How do you create a blank/empty symbol? + orig_crate_name: orig_crate_name.unwrap_or(name), + have_orig_crate_name: orig_crate_name.map(|_| ()), + crate_name: tcx.crate_name(item_def_id.krate), + name, + }), + }; } } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 26190af03587..a94cac8c7954 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -755,3 +755,23 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { diag } } + +#[derive(Diagnostic)] +#[diag(passes::duplicate_diagnostic_item)] +pub struct DuplicateDiagnosticItem { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(passes::duplicate_diagnostic_item_in_crate)] +pub struct DuplicateDiagnosticItemInCrate { + #[note(passes::diagnostic_item_first_defined)] + pub span: Option, + pub orig_crate_name: Symbol, + #[note] + pub have_orig_crate_name: Option<()>, + pub crate_name: Symbol, + pub name: Symbol, +}