Simplify lang item groups

This commit is contained in:
Cameron Steffen 2022-10-26 16:19:07 -05:00
parent 6621279a75
commit a6180ede5c
3 changed files with 73 additions and 82 deletions

View File

@ -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| {

View File

@ -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<DefId>; std::mem::variant_count::<LangItem>()],
/// Lang items that were not found during collection.
pub missing: Vec<LangItem>,
/// Mapping from [`LangItemGroup`] discriminants to all
/// [`DefId`]s of lang items in that group.
pub groups: [Vec<DefId>; NUM_GROUPS],
}
impl LanguageItems {
/// Construct an empty collection of lang items and no missing ones.
pub fn new() -> Self {
const EMPTY: Vec<DefId> = Vec::new();
Self {
items: [None; std::mem::variant_count::<LangItem>()],
missing: Vec::new(),
groups: [EMPTY; NUM_GROUPS],
}
Self { items: [None; std::mem::variant_count::<LangItem>()], missing: Vec::new() }
}
pub fn get(&self, item: LangItem) -> Option<DefId> {
@ -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<LangItemGroup> {
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<DefId> {
@ -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,
];

View File

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