migrate diagnostic_items.rs to translateable diagnostics

This commit is contained in:
Nathan Stocks 2022-09-22 18:23:05 -06:00
parent 3a748330af
commit 0609c0f1da
3 changed files with 49 additions and 19 deletions

View File

@ -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}`.

View File

@ -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,
}),
};
}
}
}

View File

@ -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,
}