From 99de57ae135420d52af00df9080c0ffe6786e83c Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Wed, 26 Oct 2022 16:17:59 -0500 Subject: [PATCH] Improve LanguageItems api --- compiler/rustc_hir/src/lang_items.rs | 59 ++++++++++++------- compiler/rustc_passes/src/reachable.rs | 8 +-- .../src/traits/error_reporting/mod.rs | 4 +- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index ca615a4912a..eaa34aeccfd 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -36,6 +36,44 @@ macro_rules! expand_group { }; } +/// All of the language items, defined or not. +/// Defined lang items can come from the current crate or its dependencies. +#[derive(HashStable_Generic, Debug)] +pub struct LanguageItems { + /// Mappings from lang items to their possibly found [`DefId`]s. + /// The index corresponds to the order in [`LangItem`]. + pub items: Vec>, + /// Lang items that were not found during collection. + pub missing: Vec, + /// Mapping from [`LangItemGroup`] discriminants to all + /// [`DefId`]s of lang items in that group. + pub groups: [Vec; NUM_GROUPS], +} + +impl LanguageItems { + pub fn get(&self, item: LangItem) -> Option { + self.items[item as usize] + } + + pub fn set(&mut self, item: LangItem, def_id: DefId) { + self.items[item as usize] = Some(def_id); + } + + /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`. + /// If it wasn't bound, e.g. due to a missing `#[lang = ""]`, + /// returns an error encapsulating the `LangItem`. + pub fn require(&self, it: LangItem) -> Result { + self.get(it).ok_or_else(|| LangItemError(it)) + } + + pub fn iter<'a>(&'a self) -> impl Iterator + 'a { + self.items + .iter() + .enumerate() + .filter_map(|(i, id)| id.map(|id| (LangItem::from_u32(i as u32).unwrap(), id))) + } +} + // The actual lang items defined come at the end of this file in one handy table. // So you probably just want to nip down to the end. macro_rules! language_item_table { @@ -82,20 +120,6 @@ macro_rules! language_item_table { } } - /// All of the language items, defined or not. - /// Defined lang items can come from the current crate or its dependencies. - #[derive(HashStable_Generic, Debug)] - pub struct LanguageItems { - /// Mappings from lang items to their possibly found [`DefId`]s. - /// The index corresponds to the order in [`LangItem`]. - pub items: Vec>, - /// Lang items that were not found during collection. - pub missing: Vec, - /// Mapping from [`LangItemGroup`] discriminants to all - /// [`DefId`]s of lang items in that group. - pub groups: [Vec; NUM_GROUPS], - } - impl LanguageItems { /// Construct an empty collection of lang items and no missing ones. pub fn new() -> Self { @@ -114,13 +138,6 @@ macro_rules! language_item_table { &*self.items } - /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`. - /// If it wasn't bound, e.g. due to a missing `#[lang = ""]`, - /// returns an error encapsulating the `LangItem`. - pub fn require(&self, it: LangItem) -> Result { - self.items[it as usize].ok_or_else(|| LangItemError(it)) - } - /// Returns the [`DefId`]s of all lang items in a group. pub fn group(&self, group: LangItemGroup) -> &[DefId] { self.groups[group as usize].as_ref() diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 10d5fc5d671..73ea06a6370 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -380,11 +380,9 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet { }) .collect::>(); - for item in tcx.lang_items().items().iter() { - if let Some(def_id) = *item { - if let Some(def_id) = def_id.as_local() { - reachable_context.worklist.push(def_id); - } + for (_, def_id) in tcx.lang_items().iter() { + if let Some(def_id) = def_id.as_local() { + reachable_context.worklist.push(def_id); } } { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 1217d264a9c..dacce5cd2f6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -974,7 +974,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // useful for less general traits. if peeled && !self.tcx.trait_is_auto(def_id) - && !self.tcx.lang_items().items().contains(&Some(def_id)) + && !self.tcx.lang_items().iter().any(|(_, id)| id == def_id) { let trait_ref = trait_pred.to_poly_trait_ref(); let impl_candidates = @@ -1898,7 +1898,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let def_id = trait_ref.def_id(); if impl_candidates.is_empty() { if self.tcx.trait_is_auto(def_id) - || self.tcx.lang_items().items().contains(&Some(def_id)) + || self.tcx.lang_items().iter().any(|(_, id)| id == def_id) || self.tcx.get_diagnostic_name(def_id).is_some() { // Mentioning implementers of `Copy`, `Debug` and friends is not useful.