diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs index af9d83f0609..5446ccb1a47 100644 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ b/compiler/rustc_const_eval/src/util/call_kind.rs @@ -3,7 +3,7 @@ //! context. use rustc_hir::def_id::DefId; -use rustc_hir::lang_items::LangItemGroup; +use rustc_hir::lang_items; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AssocItemContainer, DefIdTree, Instance, ParamEnv, Ty, TyCtxt}; use rustc_span::symbol::Ident; @@ -74,22 +74,24 @@ pub fn call_kind<'tcx>( } }); - let fn_call = parent - .and_then(|p| tcx.lang_items().group(LangItemGroup::Fn).iter().find(|did| **did == p)); + let fn_call = parent.and_then(|p| { + lang_items::FN_TRAITS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p) + }); - let operator = (!from_hir_call) - .then(|| parent) - .flatten() - .and_then(|p| tcx.lang_items().group(LangItemGroup::Op).iter().find(|did| **did == p)); + let operator = if !from_hir_call && let Some(p) = parent { + lang_items::OPERATORS.iter().filter_map(|&l| tcx.lang_items().get(l)).find(|&id| id == p) + } else { + None + }; let is_deref = !from_hir_call && tcx.is_diagnostic_item(sym::deref_method, method_did); // Check for a 'special' use of 'self' - // an FnOnce call, an operator (e.g. `<<`), or a // deref coercion. - let kind = if let Some(&trait_id) = fn_call { + let kind = if let Some(trait_id) = fn_call { Some(CallKind::FnCall { fn_trait_id: trait_id, self_ty: method_substs.type_at(0) }) - } else if let Some(&trait_id) = operator { + } else if let Some(trait_id) = operator { Some(CallKind::Operator { self_arg, trait_id, self_ty: method_substs.type_at(0) }) } else if is_deref { let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 672d3fdf28d..72ed73e81b4 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -17,22 +17,6 @@ use rustc_macros::HashStable_Generic; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -pub enum LangItemGroup { - Op, - Fn, -} - -const NUM_GROUPS: usize = 2; - -macro_rules! expand_group { - () => { - None - }; - ($group:expr) => { - Some($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)] @@ -42,21 +26,12 @@ pub struct LanguageItems { items: [Option; std::mem::variant_count::()], /// 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 { - const EMPTY: Vec = Vec::new(); - - Self { - items: [None; std::mem::variant_count::()], - missing: Vec::new(), - groups: [EMPTY; NUM_GROUPS], - } + Self { items: [None; std::mem::variant_count::()], missing: Vec::new() } } pub fn get(&self, item: LangItem) -> Option { @@ -86,7 +61,7 @@ impl LanguageItems { // So you probably just want to nip down to the end. macro_rules! language_item_table { ( - $( $(#[$attr:meta])* $variant:ident $($group:expr)?, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )* + $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )* ) => { enum_from_u32! { @@ -120,15 +95,6 @@ macro_rules! language_item_table { } } - /// The [group](LangItemGroup) that this lang item belongs to, - /// or `None` if it doesn't belong to a group. - pub fn group(self) -> Option { - use LangItemGroup::*; - match self { - $( LangItem::$variant => expand_group!($($group)*), )* - } - } - pub fn target(self) -> Target { match self { $( LangItem::$variant => $target, )* @@ -143,11 +109,6 @@ macro_rules! language_item_table { } impl LanguageItems { - /// 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() - } - $( #[doc = concat!("Returns the [`DefId`] of the `", stringify!($name), "` lang item if it is defined.")] pub fn $method(&self) -> Option { @@ -209,30 +170,30 @@ language_item_table! { TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0); TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(3); - Add(Op), sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1); - Sub(Op), sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1); - Mul(Op), sym::mul, mul_trait, Target::Trait, GenericRequirement::Exact(1); - Div(Op), sym::div, div_trait, Target::Trait, GenericRequirement::Exact(1); - Rem(Op), sym::rem, rem_trait, Target::Trait, GenericRequirement::Exact(1); - Neg(Op), sym::neg, neg_trait, Target::Trait, GenericRequirement::Exact(0); - Not(Op), sym::not, not_trait, Target::Trait, GenericRequirement::Exact(0); - BitXor(Op), sym::bitxor, bitxor_trait, Target::Trait, GenericRequirement::Exact(1); - BitAnd(Op), sym::bitand, bitand_trait, Target::Trait, GenericRequirement::Exact(1); - BitOr(Op), sym::bitor, bitor_trait, Target::Trait, GenericRequirement::Exact(1); - Shl(Op), sym::shl, shl_trait, Target::Trait, GenericRequirement::Exact(1); - Shr(Op), sym::shr, shr_trait, Target::Trait, GenericRequirement::Exact(1); - AddAssign(Op), sym::add_assign, add_assign_trait, Target::Trait, GenericRequirement::Exact(1); - SubAssign(Op), sym::sub_assign, sub_assign_trait, Target::Trait, GenericRequirement::Exact(1); - MulAssign(Op), sym::mul_assign, mul_assign_trait, Target::Trait, GenericRequirement::Exact(1); - DivAssign(Op), sym::div_assign, div_assign_trait, Target::Trait, GenericRequirement::Exact(1); - RemAssign(Op), sym::rem_assign, rem_assign_trait, Target::Trait, GenericRequirement::Exact(1); - BitXorAssign(Op), sym::bitxor_assign, bitxor_assign_trait, Target::Trait, GenericRequirement::Exact(1); - BitAndAssign(Op), sym::bitand_assign, bitand_assign_trait, Target::Trait, GenericRequirement::Exact(1); - BitOrAssign(Op), sym::bitor_assign, bitor_assign_trait, Target::Trait, GenericRequirement::Exact(1); - ShlAssign(Op), sym::shl_assign, shl_assign_trait, Target::Trait, GenericRequirement::Exact(1); - ShrAssign(Op), sym::shr_assign, shr_assign_trait, Target::Trait, GenericRequirement::Exact(1); - Index(Op), sym::index, index_trait, Target::Trait, GenericRequirement::Exact(1); - IndexMut(Op), sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1); + Add, sym::add, add_trait, Target::Trait, GenericRequirement::Exact(1); + Sub, sym::sub, sub_trait, Target::Trait, GenericRequirement::Exact(1); + Mul, sym::mul, mul_trait, Target::Trait, GenericRequirement::Exact(1); + Div, sym::div, div_trait, Target::Trait, GenericRequirement::Exact(1); + Rem, sym::rem, rem_trait, Target::Trait, GenericRequirement::Exact(1); + Neg, sym::neg, neg_trait, Target::Trait, GenericRequirement::Exact(0); + Not, sym::not, not_trait, Target::Trait, GenericRequirement::Exact(0); + BitXor, sym::bitxor, bitxor_trait, Target::Trait, GenericRequirement::Exact(1); + BitAnd, sym::bitand, bitand_trait, Target::Trait, GenericRequirement::Exact(1); + BitOr, sym::bitor, bitor_trait, Target::Trait, GenericRequirement::Exact(1); + Shl, sym::shl, shl_trait, Target::Trait, GenericRequirement::Exact(1); + Shr, sym::shr, shr_trait, Target::Trait, GenericRequirement::Exact(1); + AddAssign, sym::add_assign, add_assign_trait, Target::Trait, GenericRequirement::Exact(1); + SubAssign, sym::sub_assign, sub_assign_trait, Target::Trait, GenericRequirement::Exact(1); + MulAssign, sym::mul_assign, mul_assign_trait, Target::Trait, GenericRequirement::Exact(1); + DivAssign, sym::div_assign, div_assign_trait, Target::Trait, GenericRequirement::Exact(1); + RemAssign, sym::rem_assign, rem_assign_trait, Target::Trait, GenericRequirement::Exact(1); + BitXorAssign, sym::bitxor_assign, bitxor_assign_trait, Target::Trait, GenericRequirement::Exact(1); + BitAndAssign, sym::bitand_assign, bitand_assign_trait, Target::Trait, GenericRequirement::Exact(1); + BitOrAssign, sym::bitor_assign, bitor_assign_trait, Target::Trait, GenericRequirement::Exact(1); + ShlAssign, sym::shl_assign, shl_assign_trait, Target::Trait, GenericRequirement::Exact(1); + ShrAssign, sym::shr_assign, shr_assign_trait, Target::Trait, GenericRequirement::Exact(1); + Index, sym::index, index_trait, Target::Trait, GenericRequirement::Exact(1); + IndexMut, sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1); UnsafeCell, sym::unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None; VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None; @@ -242,9 +203,9 @@ language_item_table! { DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None; Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None; - Fn(Fn), kw::Fn, fn_trait, Target::Trait, GenericRequirement::Exact(1); - FnMut(Fn), sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); - FnOnce(Fn), sym::fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1); + Fn, kw::Fn, fn_trait, Target::Trait, GenericRequirement::Exact(1); + FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); + FnOnce, sym::fn_once, fn_once_trait, Target::Trait, GenericRequirement::Exact(1); FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; @@ -254,8 +215,8 @@ language_item_table! { Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None; - PartialEq(Op), sym::eq, eq_trait, Target::Trait, GenericRequirement::Exact(1); - PartialOrd(Op), sym::partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1); + PartialEq, sym::eq, eq_trait, Target::Trait, GenericRequirement::Exact(1); + PartialOrd, sym::partial_ord, partial_ord_trait, Target::Trait, GenericRequirement::Exact(1); // A number of panic-related lang items. The `panic` item corresponds to divide-by-zero and // various panic cases with `match`. The `panic_bounds_check` item is for indexing arrays. @@ -351,3 +312,34 @@ pub enum GenericRequirement { Minimum(usize), Exact(usize), } + +pub static FN_TRAITS: &'static [LangItem] = &[LangItem::Fn, LangItem::FnMut, LangItem::FnOnce]; + +pub static OPERATORS: &'static [LangItem] = &[ + LangItem::Add, + LangItem::Sub, + LangItem::Mul, + LangItem::Div, + LangItem::Rem, + LangItem::Neg, + LangItem::Not, + LangItem::BitXor, + LangItem::BitAnd, + LangItem::BitOr, + LangItem::Shl, + LangItem::Shr, + LangItem::AddAssign, + LangItem::SubAssign, + LangItem::MulAssign, + LangItem::DivAssign, + LangItem::RemAssign, + LangItem::BitXorAssign, + LangItem::BitAndAssign, + LangItem::BitOrAssign, + LangItem::ShlAssign, + LangItem::ShrAssign, + LangItem::Index, + LangItem::IndexMut, + LangItem::PartialEq, + LangItem::PartialOrd, +]; diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 54be30d9fe5..188efc528ef 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -140,9 +140,6 @@ impl<'tcx> LanguageItemCollector<'tcx> { // Matched. self.items.set(lang_item, item_def_id); - if let Some(group) = lang_item.group() { - self.items.groups[group as usize].push(item_def_id); - } } // Like collect_item() above, but also checks whether the lang item is declared