From: Cameron Steffen Date: Mon, 4 Oct 2021 20:57:39 +0000 (-0500) Subject: Introduce get_diagnostic_name X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=33b9b9530561ada2584c8a9239e6581fef216a2a;hp=d7539a6af09e5889ed9bcb8b49571b7a59c32e65;p=rust.git Introduce get_diagnostic_name --- diff --git a/compiler/rustc_hir/src/diagnostic_items.rs b/compiler/rustc_hir/src/diagnostic_items.rs new file mode 100644 index 00000000000..243014b0027 --- /dev/null +++ b/compiler/rustc_hir/src/diagnostic_items.rs @@ -0,0 +1,17 @@ +use crate::def_id::DefId; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_span::Symbol; + +#[derive(Debug, Default)] +pub struct DiagnosticItems { + pub id_to_name: FxHashMap, + pub name_to_id: FxHashMap, +} + +impl HashStable for DiagnosticItems { + #[inline] + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.name_to_id.hash_stable(ctx, hasher); + } +} diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index ce36648d6df..f5ea044e248 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -18,6 +18,7 @@ pub mod def; pub mod def_path_hash_map; pub mod definitions; +pub mod diagnostic_items; pub use rustc_span::def_id; mod hir; pub mod hir_id; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 08fc11f21d9..c7d0f594f01 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -18,6 +18,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; +use rustc_hir::diagnostic_items::DiagnosticItems; use rustc_hir::lang_items; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::hir::exports::Export; @@ -1052,16 +1053,23 @@ fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { } /// Iterates over the diagnostic items in the given crate. - fn get_diagnostic_items(&self) -> FxHashMap { + fn get_diagnostic_items(&self) -> DiagnosticItems { if self.root.is_proc_macro_crate() { // Proc macro crates do not export any diagnostic-items to the target. Default::default() } else { - self.root + let mut id_to_name = FxHashMap::default(); + let name_to_id = self + .root .diagnostic_items .decode(self) - .map(|(name, def_index)| (name, self.local_def_id(def_index))) - .collect() + .map(|(name, def_index)| { + let id = self.local_def_id(def_index); + id_to_name.insert(id, name); + (name, id) + }) + .collect(); + DiagnosticItems { id_to_name, name_to_id } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 072398983af..dacb1e4029c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1750,7 +1750,7 @@ fn encode_lib_features(&mut self) -> Lazy<[(Symbol, Option)]> { fn encode_diagnostic_items(&mut self) -> Lazy<[(Symbol, DefIndex)]> { empty_proc_macro!(self); let tcx = self.tcx; - let diagnostic_items = tcx.diagnostic_items(LOCAL_CRATE); + let diagnostic_items = &tcx.diagnostic_items(LOCAL_CRATE).name_to_id; self.lazy(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index))) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b4f7a9fa8e9..9b0b1377875 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1442,7 +1442,7 @@ } /// Returns all diagnostic items defined in all crates. - query all_diagnostic_items(_: ()) -> FxHashMap { + query all_diagnostic_items(_: ()) -> rustc_hir::diagnostic_items::DiagnosticItems { storage(ArenaCacheSelector<'tcx>) eval_always desc { "calculating the diagnostic items map" } @@ -1454,7 +1454,7 @@ } /// Returns the diagnostic items defined in a crate. - query diagnostic_items(_: CrateNum) -> FxHashMap { + query diagnostic_items(_: CrateNum) -> rustc_hir::diagnostic_items::DiagnosticItems { storage(ArenaCacheSelector<'tcx>) desc { "calculating the diagnostic items map in a crate" } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 080e2fef203..6a6fb30dce8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1232,12 +1232,17 @@ pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems { /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to /// compare against another `DefId`, since `is_diagnostic_item` is cheaper. pub fn get_diagnostic_item(self, name: Symbol) -> Option { - self.all_diagnostic_items(()).get(&name).copied() + self.all_diagnostic_items(()).name_to_id.get(&name).copied() + } + + /// Obtain the diagnostic item's name + pub fn get_diagnostic_name(self, id: DefId) -> Option { + self.diagnostic_items(id.krate).id_to_name.get(&id).copied() } /// Check whether the diagnostic item with the given `name` has the given `DefId`. pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool { - self.diagnostic_items(did.krate).get(&name) == Some(&did) + self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did) } pub fn stability(self) -> &'tcx stability::Index<'tcx> { diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index d35a1cc293e..30a0071f0f2 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -10,8 +10,8 @@ //! * Compiler internal types like `Ty` and `TyCtxt` use rustc_ast as ast; -use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; +use rustc_hir::diagnostic_items::DiagnosticItems; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; @@ -19,9 +19,8 @@ use rustc_span::symbol::{sym, Symbol}; struct DiagnosticItemCollector<'tcx> { - // items from this crate - items: FxHashMap, tcx: TyCtxt<'tcx>, + diagnostic_items: DiagnosticItems, } impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> { @@ -44,7 +43,7 @@ fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem<'_>) { impl<'tcx> DiagnosticItemCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> DiagnosticItemCollector<'tcx> { - DiagnosticItemCollector { tcx, items: Default::default() } + DiagnosticItemCollector { tcx, diagnostic_items: DiagnosticItems::default() } } fn observe_item(&mut self, def_id: LocalDefId) { @@ -52,19 +51,14 @@ fn observe_item(&mut self, def_id: LocalDefId) { let attrs = self.tcx.hir().attrs(hir_id); if let Some(name) = extract(attrs) { // insert into our table - collect_item(self.tcx, &mut self.items, name, def_id.to_def_id()); + collect_item(self.tcx, &mut self.diagnostic_items, name, def_id.to_def_id()); } } } -fn collect_item( - tcx: TyCtxt<'_>, - items: &mut FxHashMap, - name: Symbol, - item_def_id: DefId, -) { - // Check for duplicates. - if let Some(original_def_id) = items.insert(name, item_def_id) { +fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item_def_id: DefId) { + 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( @@ -98,7 +92,7 @@ fn extract(attrs: &[ast::Attribute]) -> Option { } /// Traverse and collect the diagnostic items in the current -fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap { +fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> DiagnosticItems { assert_eq!(cnum, LOCAL_CRATE); // Initialize the collector. @@ -107,22 +101,22 @@ fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap(tcx: TyCtxt<'tcx>, (): ()) -> FxHashMap { +fn all_diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> DiagnosticItems { // Initialize the collector. - let mut collector = FxHashMap::default(); + let mut items = DiagnosticItems::default(); // Collect diagnostic items in other crates. for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) { - for (&name, &def_id) in tcx.diagnostic_items(cnum).iter() { - collect_item(tcx, &mut collector, name, def_id); + for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id { + collect_item(tcx, &mut items, name, def_id); } } - collector + items } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index cd678b96446..a73d2285d45 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1636,12 +1636,12 @@ fn note_obligation_cause_for_async_await( // Special case the primary error message when send or sync is the trait that was // not implemented. - let is_send = self.tcx.is_diagnostic_item(sym::Send, trait_ref.def_id); - let is_sync = self.tcx.is_diagnostic_item(sym::Sync, trait_ref.def_id); let hir = self.tcx.hir(); - let trait_explanation = if is_send || is_sync { + let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) = + self.tcx.get_diagnostic_name(trait_ref.def_id) + { let (trait_name, trait_verb) = - if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") }; + if name == sym::Send { ("`Send`", "sent") } else { ("`Sync`", "shared") }; err.clear_code(); err.set_primary_message(format!( diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 8c7ec219464..41281a6748f 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1076,7 +1076,7 @@ fn suggest_derive( if adt_def.did.is_local() { let diagnostic_items = self.tcx.diagnostic_items(trait_ref.def_id.krate); return derivables.iter().find_map(|trait_derivable| { - let item_def_id = diagnostic_items.get(trait_derivable)?; + let item_def_id = diagnostic_items.name_to_id.get(trait_derivable)?; if item_def_id == &trait_pred.trait_ref.def_id && !(adt_def.is_enum() && *trait_derivable == sym::Default) {