Skip to content

Commit 33b9b95

Browse files
committed
Introduce get_diagnostic_name
1 parent d7539a6 commit 33b9b95

File tree

9 files changed

+59
-34
lines changed

9 files changed

+59
-34
lines changed
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::def_id::DefId;
2+
use rustc_data_structures::fx::FxHashMap;
3+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4+
use rustc_span::Symbol;
5+
6+
#[derive(Debug, Default)]
7+
pub struct DiagnosticItems {
8+
pub id_to_name: FxHashMap<DefId, Symbol>,
9+
pub name_to_id: FxHashMap<Symbol, DefId>,
10+
}
11+
12+
impl<CTX: crate::HashStableContext> HashStable<CTX> for DiagnosticItems {
13+
#[inline]
14+
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
15+
self.name_to_id.hash_stable(ctx, hasher);
16+
}
17+
}

compiler/rustc_hir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod arena;
1818
pub mod def;
1919
pub mod def_path_hash_map;
2020
pub mod definitions;
21+
pub mod diagnostic_items;
2122
pub use rustc_span::def_id;
2223
mod hir;
2324
pub mod hir_id;

compiler/rustc_metadata/src/rmeta/decoder.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_hir as hir;
1818
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
1919
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
2020
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
21+
use rustc_hir::diagnostic_items::DiagnosticItems;
2122
use rustc_hir::lang_items;
2223
use rustc_index::vec::{Idx, IndexVec};
2324
use rustc_middle::hir::exports::Export;
@@ -1052,16 +1053,23 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10521053
}
10531054

10541055
/// Iterates over the diagnostic items in the given crate.
1055-
fn get_diagnostic_items(&self) -> FxHashMap<Symbol, DefId> {
1056+
fn get_diagnostic_items(&self) -> DiagnosticItems {
10561057
if self.root.is_proc_macro_crate() {
10571058
// Proc macro crates do not export any diagnostic-items to the target.
10581059
Default::default()
10591060
} else {
1060-
self.root
1061+
let mut id_to_name = FxHashMap::default();
1062+
let name_to_id = self
1063+
.root
10611064
.diagnostic_items
10621065
.decode(self)
1063-
.map(|(name, def_index)| (name, self.local_def_id(def_index)))
1064-
.collect()
1066+
.map(|(name, def_index)| {
1067+
let id = self.local_def_id(def_index);
1068+
id_to_name.insert(id, name);
1069+
(name, id)
1070+
})
1071+
.collect();
1072+
DiagnosticItems { id_to_name, name_to_id }
10651073
}
10661074
}
10671075

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,7 @@ impl EncodeContext<'a, 'tcx> {
17501750
fn encode_diagnostic_items(&mut self) -> Lazy<[(Symbol, DefIndex)]> {
17511751
empty_proc_macro!(self);
17521752
let tcx = self.tcx;
1753-
let diagnostic_items = tcx.diagnostic_items(LOCAL_CRATE);
1753+
let diagnostic_items = &tcx.diagnostic_items(LOCAL_CRATE).name_to_id;
17541754
self.lazy(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index)))
17551755
}
17561756

compiler/rustc_middle/src/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ rustc_queries! {
14421442
}
14431443

14441444
/// Returns all diagnostic items defined in all crates.
1445-
query all_diagnostic_items(_: ()) -> FxHashMap<Symbol, DefId> {
1445+
query all_diagnostic_items(_: ()) -> rustc_hir::diagnostic_items::DiagnosticItems {
14461446
storage(ArenaCacheSelector<'tcx>)
14471447
eval_always
14481448
desc { "calculating the diagnostic items map" }
@@ -1454,7 +1454,7 @@ rustc_queries! {
14541454
}
14551455

14561456
/// Returns the diagnostic items defined in a crate.
1457-
query diagnostic_items(_: CrateNum) -> FxHashMap<Symbol, DefId> {
1457+
query diagnostic_items(_: CrateNum) -> rustc_hir::diagnostic_items::DiagnosticItems {
14581458
storage(ArenaCacheSelector<'tcx>)
14591459
desc { "calculating the diagnostic items map in a crate" }
14601460
}

compiler/rustc_middle/src/ty/context.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1232,12 +1232,17 @@ impl<'tcx> TyCtxt<'tcx> {
12321232
/// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
12331233
/// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
12341234
pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
1235-
self.all_diagnostic_items(()).get(&name).copied()
1235+
self.all_diagnostic_items(()).name_to_id.get(&name).copied()
1236+
}
1237+
1238+
/// Obtain the diagnostic item's name
1239+
pub fn get_diagnostic_name(self, id: DefId) -> Option<Symbol> {
1240+
self.diagnostic_items(id.krate).id_to_name.get(&id).copied()
12361241
}
12371242

12381243
/// Check whether the diagnostic item with the given `name` has the given `DefId`.
12391244
pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
1240-
self.diagnostic_items(did.krate).get(&name) == Some(&did)
1245+
self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
12411246
}
12421247

12431248
pub fn stability(self) -> &'tcx stability::Index<'tcx> {

compiler/rustc_passes/src/diagnostic_items.rs

+14-20
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,17 @@
1010
//! * Compiler internal types like `Ty` and `TyCtxt`
1111
1212
use rustc_ast as ast;
13-
use rustc_data_structures::fx::FxHashMap;
1413
use rustc_hir as hir;
14+
use rustc_hir::diagnostic_items::DiagnosticItems;
1515
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1616
use rustc_middle::ty::query::Providers;
1717
use rustc_middle::ty::TyCtxt;
1818
use rustc_span::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
1919
use rustc_span::symbol::{sym, Symbol};
2020

2121
struct DiagnosticItemCollector<'tcx> {
22-
// items from this crate
23-
items: FxHashMap<Symbol, DefId>,
2422
tcx: TyCtxt<'tcx>,
23+
diagnostic_items: DiagnosticItems,
2524
}
2625

2726
impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> {
@@ -44,27 +43,22 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> {
4443

4544
impl<'tcx> DiagnosticItemCollector<'tcx> {
4645
fn new(tcx: TyCtxt<'tcx>) -> DiagnosticItemCollector<'tcx> {
47-
DiagnosticItemCollector { tcx, items: Default::default() }
46+
DiagnosticItemCollector { tcx, diagnostic_items: DiagnosticItems::default() }
4847
}
4948

5049
fn observe_item(&mut self, def_id: LocalDefId) {
5150
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
5251
let attrs = self.tcx.hir().attrs(hir_id);
5352
if let Some(name) = extract(attrs) {
5453
// insert into our table
55-
collect_item(self.tcx, &mut self.items, name, def_id.to_def_id());
54+
collect_item(self.tcx, &mut self.diagnostic_items, name, def_id.to_def_id());
5655
}
5756
}
5857
}
5958

60-
fn collect_item(
61-
tcx: TyCtxt<'_>,
62-
items: &mut FxHashMap<Symbol, DefId>,
63-
name: Symbol,
64-
item_def_id: DefId,
65-
) {
66-
// Check for duplicates.
67-
if let Some(original_def_id) = items.insert(name, item_def_id) {
59+
fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item_def_id: DefId) {
60+
items.id_to_name.insert(item_def_id, name);
61+
if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) {
6862
if original_def_id != item_def_id {
6963
let mut err = match tcx.hir().span_if_local(item_def_id) {
7064
Some(span) => tcx.sess.struct_span_err(
@@ -98,7 +92,7 @@ fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
9892
}
9993

10094
/// Traverse and collect the diagnostic items in the current
101-
fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap<Symbol, DefId> {
95+
fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> DiagnosticItems {
10296
assert_eq!(cnum, LOCAL_CRATE);
10397

10498
// Initialize the collector.
@@ -107,22 +101,22 @@ fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap<Symbol
107101
// Collect diagnostic items in this crate.
108102
tcx.hir().visit_all_item_likes(&mut collector);
109103

110-
collector.items
104+
collector.diagnostic_items
111105
}
112106

113107
/// Traverse and collect all the diagnostic items in all crates.
114-
fn all_diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashMap<Symbol, DefId> {
108+
fn all_diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> DiagnosticItems {
115109
// Initialize the collector.
116-
let mut collector = FxHashMap::default();
110+
let mut items = DiagnosticItems::default();
117111

118112
// Collect diagnostic items in other crates.
119113
for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
120-
for (&name, &def_id) in tcx.diagnostic_items(cnum).iter() {
121-
collect_item(tcx, &mut collector, name, def_id);
114+
for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
115+
collect_item(tcx, &mut items, name, def_id);
122116
}
123117
}
124118

125-
collector
119+
items
126120
}
127121

128122
pub fn provide(providers: &mut Providers) {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1636,12 +1636,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
16361636

16371637
// Special case the primary error message when send or sync is the trait that was
16381638
// not implemented.
1639-
let is_send = self.tcx.is_diagnostic_item(sym::Send, trait_ref.def_id);
1640-
let is_sync = self.tcx.is_diagnostic_item(sym::Sync, trait_ref.def_id);
16411639
let hir = self.tcx.hir();
1642-
let trait_explanation = if is_send || is_sync {
1640+
let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) =
1641+
self.tcx.get_diagnostic_name(trait_ref.def_id)
1642+
{
16431643
let (trait_name, trait_verb) =
1644-
if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
1644+
if name == sym::Send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
16451645

16461646
err.clear_code();
16471647
err.set_primary_message(format!(

compiler/rustc_typeck/src/check/method/suggest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10761076
if adt_def.did.is_local() {
10771077
let diagnostic_items = self.tcx.diagnostic_items(trait_ref.def_id.krate);
10781078
return derivables.iter().find_map(|trait_derivable| {
1079-
let item_def_id = diagnostic_items.get(trait_derivable)?;
1079+
let item_def_id = diagnostic_items.name_to_id.get(trait_derivable)?;
10801080
if item_def_id == &trait_pred.trait_ref.def_id
10811081
&& !(adt_def.is_enum() && *trait_derivable == sym::Default)
10821082
{

0 commit comments

Comments
 (0)