about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Stocks <cleancut@github.com>2022-09-22 18:23:05 -0600
committerNathan Stocks <cleancut@github.com>2022-10-07 13:19:27 -0600
commit0609c0f1da13c8b0aeb90b5ff66f527bb16d58bf (patch)
tree3c38fa497dea8dc95be07c67c442999e5bdea16e
parent3a748330af35ec9da4b07f55b78e8f08f2af0888 (diff)
downloadrust-0609c0f1da13c8b0aeb90b5ff66f527bb16d58bf.tar.gz
rust-0609c0f1da13c8b0aeb90b5ff66f527bb16d58bf.zip
migrate diagnostic_items.rs to translateable diagnostics
-rw-r--r--compiler/rustc_error_messages/locales/en-US/passes.ftl12
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs36
-rw-r--r--compiler/rustc_passes/src/errors.rs20
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 49cd2ee1758..04fd0a3a6ac 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 e428d9293db..c411a247165 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 26190af0358..a94cac8c795 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<Span>,
+    pub orig_crate_name: Symbol,
+    #[note]
+    pub have_orig_crate_name: Option<()>,
+    pub crate_name: Symbol,
+    pub name: Symbol,
+}