Unnamed repository; edit this file 'description' to name the repository.
Cache more things that are related to lang items (paren traits, children/sibling assoc types/functions) but are not lang items themselves
And make use of them.
Chayim Refael Friedman 13 days ago
parent b4ca747 · commit 4a90a52
-rw-r--r--crates/hir-def/src/lang_item.rs168
-rw-r--r--crates/hir-ty/src/display.rs24
-rw-r--r--crates/hir-ty/src/infer/callee.rs32
-rw-r--r--crates/hir-ty/src/infer/op.rs27
-rw-r--r--crates/hir-ty/src/infer/place_op.rs17
-rw-r--r--crates/hir-ty/src/lang_items.rs57
-rw-r--r--crates/hir-ty/src/lib.rs5
-rw-r--r--crates/hir-ty/src/method_resolution.rs10
-rw-r--r--crates/hir-ty/src/method_resolution/confirm.rs6
-rw-r--r--crates/hir-ty/src/mir/eval.rs33
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs7
-rw-r--r--crates/hir-ty/src/mir/lower/as_place.rs24
-rw-r--r--crates/hir/src/lib.rs29
-rw-r--r--crates/hir/src/source_analyzer.rs52
14 files changed, 269 insertions, 222 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index e5a9b5d46c..c2cbb9eda7 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -194,16 +194,115 @@ fn resolve_core_macro(
impl LangItems {
fn resolve_manually(&mut self, db: &dyn DefDatabase) {
- (|| {
- let into_future_into_future = self.IntoFutureIntoFuture?;
- let ItemContainerId::TraitId(into_future) = into_future_into_future.loc(db).container
- else {
- return None;
+ let parent_trait =
+ |lang_item: &mut Option<TraitId>, def: Option<FunctionId>| match def?.loc(db).container
+ {
+ ItemContainerId::TraitId(trait_) => {
+ *lang_item = Some(trait_);
+ Some(trait_)
+ }
+ _ => None,
+ };
+ let assoc_types =
+ |trait_: TraitId, assoc_types: &mut [(&mut Option<TypeAliasId>, Symbol)]| {
+ let trait_items = trait_.trait_items(db);
+ for (assoc_type, name) in assoc_types {
+ **assoc_type =
+ trait_items.associated_type_by_name(&Name::new_symbol_root(name.clone()));
+ }
};
- self.IntoFuture = Some(into_future);
- self.IntoFutureOutput = into_future
- .trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Output));
+ let methods = |trait_: TraitId, assoc_types: &mut [(&mut Option<FunctionId>, Symbol)]| {
+ let trait_items = trait_.trait_items(db);
+ for (assoc_type, name) in assoc_types {
+ **assoc_type = trait_items.method_by_name(&Name::new_symbol_root(name.clone()));
+ }
+ };
+ (|| {
+ let into_future = parent_trait(&mut self.IntoFuture, self.IntoFutureIntoFuture)?;
+ assoc_types(into_future, &mut [(&mut self.IntoFutureOutput, sym::Output)]);
+ Some(())
+ })();
+
+ (|| {
+ let into_iterator = parent_trait(&mut self.IntoIterator, self.IntoIterIntoIter)?;
+ assoc_types(
+ into_iterator,
+ &mut [
+ (&mut self.IntoIteratorItem, sym::Item),
+ (&mut self.IntoIterIntoIterType, sym::IntoIter),
+ ],
+ );
+ Some(())
+ })();
+
+ (|| {
+ assoc_types(self.Iterator?, &mut [(&mut self.IteratorItem, sym::Item)]);
+ Some(())
+ })();
+
+ (|| {
+ assoc_types(self.AsyncIterator?, &mut [(&mut self.AsyncIteratorItem, sym::Item)]);
+ Some(())
+ })();
+
+ for (op_trait, op_method, op_method_name) in [
+ (self.Fn, &mut self.Fn_call, sym::call),
+ (self.FnMut, &mut self.FnMut_call_mut, sym::call_mut),
+ (self.FnOnce, &mut self.FnOnce_call_once, sym::call_once),
+ (self.AsyncFn, &mut self.AsyncFn_async_call, sym::async_call),
+ (self.AsyncFnMut, &mut self.AsyncFnMut_async_call_mut, sym::async_call_mut),
+ (self.AsyncFnOnce, &mut self.AsyncFnOnce_async_call_once, sym::async_call_once),
+ (self.Not, &mut self.Not_not, sym::not),
+ (self.Neg, &mut self.Neg_neg, sym::neg),
+ (self.Add, &mut self.Add_add, sym::add),
+ (self.Mul, &mut self.Mul_mul, sym::mul),
+ (self.Sub, &mut self.Sub_sub, sym::sub),
+ (self.Div, &mut self.Div_div, sym::div),
+ (self.Rem, &mut self.Rem_rem, sym::rem),
+ (self.Shl, &mut self.Shl_shl, sym::shl),
+ (self.Shr, &mut self.Shr_shr, sym::shr),
+ (self.BitXor, &mut self.BitXor_bitxor, sym::bitxor),
+ (self.BitOr, &mut self.BitOr_bitor, sym::bitor),
+ (self.BitAnd, &mut self.BitAnd_bitand, sym::bitand),
+ (self.AddAssign, &mut self.AddAssign_add_assign, sym::add_assign),
+ (self.MulAssign, &mut self.MulAssign_mul_assign, sym::mul_assign),
+ (self.SubAssign, &mut self.SubAssign_sub_assign, sym::sub_assign),
+ (self.DivAssign, &mut self.DivAssign_div_assign, sym::div_assign),
+ (self.RemAssign, &mut self.RemAssign_rem_assign, sym::rem_assign),
+ (self.ShlAssign, &mut self.ShlAssign_shl_assign, sym::shl_assign),
+ (self.ShrAssign, &mut self.ShrAssign_shr_assign, sym::shr_assign),
+ (self.BitXorAssign, &mut self.BitXorAssign_bitxor_assign, sym::bitxor_assign),
+ (self.BitOrAssign, &mut self.BitOrAssign_bitor_assign, sym::bitor_assign),
+ (self.BitAndAssign, &mut self.BitAndAssign_bitand_assign, sym::bitand_assign),
+ (self.Drop, &mut self.Drop_drop, sym::drop),
+ (self.Debug, &mut self.Debug_fmt, sym::fmt),
+ (self.Deref, &mut self.Deref_deref, sym::deref),
+ (self.DerefMut, &mut self.DerefMut_deref_mut, sym::deref_mut),
+ (self.Index, &mut self.Index_index, sym::index),
+ (self.IndexMut, &mut self.IndexMut_index_mut, sym::index_mut),
+ ] {
+ (|| {
+ methods(op_trait?, &mut [(op_method, op_method_name)]);
+ Some(())
+ })();
+ }
+ (|| {
+ methods(
+ self.PartialEq?,
+ &mut [(&mut self.PartialEq_eq, sym::eq), (&mut self.PartialEq_ne, sym::ne)],
+ );
+ Some(())
+ })();
+ (|| {
+ methods(
+ self.PartialOrd?,
+ &mut [
+ (&mut self.PartialOrd_le, sym::le),
+ (&mut self.PartialOrd_lt, sym::lt),
+ (&mut self.PartialOrd_ge, sym::ge),
+ (&mut self.PartialOrd_gt, sym::gt),
+ ],
+ );
Some(())
})();
}
@@ -567,6 +666,53 @@ language_item_table! { LangItems =>
core::clone, Clone, CloneDerive;
@resolve_manually:
- IntoFuture, TraitId;
- IntoFutureOutput, TypeAliasId;
+
+ IntoFuture, TraitId;
+ IntoFutureOutput, TypeAliasId;
+ IntoIterator, TraitId;
+ IntoIteratorItem, TypeAliasId;
+ IntoIterIntoIterType, TypeAliasId;
+ IteratorItem, TypeAliasId;
+ AsyncIteratorItem, TypeAliasId;
+
+ Fn_call, FunctionId;
+ FnMut_call_mut, FunctionId;
+ FnOnce_call_once, FunctionId;
+ AsyncFn_async_call, FunctionId;
+ AsyncFnMut_async_call_mut, FunctionId;
+ AsyncFnOnce_async_call_once, FunctionId;
+ Not_not, FunctionId;
+ Neg_neg, FunctionId;
+ Add_add, FunctionId;
+ Mul_mul, FunctionId;
+ Sub_sub, FunctionId;
+ Div_div, FunctionId;
+ Rem_rem, FunctionId;
+ Shl_shl, FunctionId;
+ Shr_shr, FunctionId;
+ BitXor_bitxor, FunctionId;
+ BitOr_bitor, FunctionId;
+ BitAnd_bitand, FunctionId;
+ AddAssign_add_assign, FunctionId;
+ MulAssign_mul_assign, FunctionId;
+ SubAssign_sub_assign, FunctionId;
+ DivAssign_div_assign, FunctionId;
+ RemAssign_rem_assign, FunctionId;
+ ShlAssign_shl_assign, FunctionId;
+ ShrAssign_shr_assign, FunctionId;
+ BitXorAssign_bitxor_assign, FunctionId;
+ BitOrAssign_bitor_assign, FunctionId;
+ BitAndAssign_bitand_assign, FunctionId;
+ PartialEq_eq, FunctionId;
+ PartialEq_ne, FunctionId;
+ PartialOrd_le, FunctionId;
+ PartialOrd_lt, FunctionId;
+ PartialOrd_ge, FunctionId;
+ PartialOrd_gt, FunctionId;
+ Drop_drop, FunctionId;
+ Debug_fmt, FunctionId;
+ Deref_deref, FunctionId;
+ DerefMut_deref_mut, FunctionId;
+ Index_index, FunctionId;
+ IndexMut_index_mut, FunctionId;
}
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index f7d333f94c..7c80066b49 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -1726,11 +1726,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
subst.split_coroutine_args();
match kind {
HirClosureKind::Coroutine { kind: CoroutineKind::Async, .. } => {
- let future_trait = f.lang_items().Future;
- let output = future_trait.and_then(|t| {
- t.trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Output))
- });
+ let lang_items = f.lang_items();
+ let future_trait = lang_items.Future;
+ let output = lang_items.FutureOutput;
write!(f, "impl ")?;
if let Some(t) = future_trait {
f.start_location_link(t.into());
@@ -1752,11 +1750,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
write!(f, ">")?;
}
HirClosureKind::Coroutine { kind: CoroutineKind::Gen, .. } => {
- let iterator_trait = f.lang_items().Iterator;
- let item = iterator_trait.and_then(|t| {
- t.trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Item))
- });
+ let lang_items = f.lang_items();
+ let iterator_trait = lang_items.Iterator;
+ let item = lang_items.IteratorItem;
write!(f, "impl ")?;
if let Some(t) = iterator_trait {
f.start_location_link(t.into());
@@ -1778,11 +1774,9 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
write!(f, ">")?;
}
HirClosureKind::Coroutine { kind: CoroutineKind::AsyncGen, .. } => {
- let async_iterator_trait = f.lang_items().AsyncIterator;
- let item = async_iterator_trait.and_then(|t| {
- t.trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Item))
- });
+ let lang_items = f.lang_items();
+ let async_iterator_trait = lang_items.AsyncIterator;
+ let item = lang_items.AsyncIteratorItem;
write!(f, "impl ")?;
if let Some(t) = async_iterator_trait {
f.start_location_link(t.into());
diff --git a/crates/hir-ty/src/infer/callee.rs b/crates/hir-ty/src/infer/callee.rs
index 9c134cb75f..2d1584aa4f 100644
--- a/crates/hir-ty/src/infer/callee.rs
+++ b/crates/hir-ty/src/infer/callee.rs
@@ -2,7 +2,6 @@
use std::iter;
-use intern::sym;
use tracing::debug;
use hir_def::{CallableDefId, ConstParamId, hir::ExprId, signatures::FunctionSignature};
@@ -277,27 +276,28 @@ impl<'db> InferenceContext<'_, 'db> {
let call_trait_choices = if self.shallow_resolve(adjusted_ty).is_coroutine_closure() {
[
- (self.lang_items.AsyncFn, sym::async_call, true),
- (self.lang_items.AsyncFnMut, sym::async_call_mut, true),
- (self.lang_items.AsyncFnOnce, sym::async_call_once, false),
- (self.lang_items.Fn, sym::call, true),
- (self.lang_items.FnMut, sym::call_mut, true),
- (self.lang_items.FnOnce, sym::call_once, false),
+ (self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
+ (self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
+ (self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
+ (self.lang_items.Fn, self.lang_items.Fn_call, true),
+ (self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
+ (self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
]
} else {
[
- (self.lang_items.Fn, sym::call, true),
- (self.lang_items.FnMut, sym::call_mut, true),
- (self.lang_items.FnOnce, sym::call_once, false),
- (self.lang_items.AsyncFn, sym::async_call, true),
- (self.lang_items.AsyncFnMut, sym::async_call_mut, true),
- (self.lang_items.AsyncFnOnce, sym::async_call_once, false),
+ (self.lang_items.Fn, self.lang_items.Fn_call, true),
+ (self.lang_items.FnMut, self.lang_items.FnMut_call_mut, true),
+ (self.lang_items.FnOnce, self.lang_items.FnOnce_call_once, false),
+ (self.lang_items.AsyncFn, self.lang_items.AsyncFn_async_call, true),
+ (self.lang_items.AsyncFnMut, self.lang_items.AsyncFnMut_async_call_mut, true),
+ (self.lang_items.AsyncFnOnce, self.lang_items.AsyncFnOnce_async_call_once, false),
]
};
// Try the options that are least restrictive on the caller first.
- for (opt_trait_def_id, method_name, borrow) in call_trait_choices {
- let Some(trait_def_id) = opt_trait_def_id else {
+ for (opt_trait_def_id, opt_method_def_id, borrow) in call_trait_choices {
+ let (Some(trait_def_id), Some(method_def_id)) = (opt_trait_def_id, opt_method_def_id)
+ else {
continue;
};
@@ -316,8 +316,8 @@ impl<'db> InferenceContext<'_, 'db> {
// `Box<impl FnOnce()>: Fn` is considered ambiguous and chosen.
if let Some(ok) = self.table.lookup_method_for_operator(
ObligationCause::new(call_expr),
- method_name,
trait_def_id,
+ method_def_id,
adjusted_ty,
opt_input_type,
TreatNotYetDefinedOpaques::AsRigid,
diff --git a/crates/hir-ty/src/infer/op.rs b/crates/hir-ty/src/infer/op.rs
index 0127fd6cdb..9119af9628 100644
--- a/crates/hir-ty/src/infer/op.rs
+++ b/crates/hir-ty/src/infer/op.rs
@@ -2,8 +2,7 @@
use std::collections::hash_map;
-use hir_def::{GenericParamId, TraitId, hir::ExprId};
-use intern::{Symbol, sym};
+use hir_def::{FunctionId, GenericParamId, TraitId, hir::ExprId};
use rustc_ast_ir::Mutability;
use rustc_type_ir::inherent::{IntoKind, Ty as _};
use syntax::ast::{ArithOp, BinaryOp, UnaryOp};
@@ -283,16 +282,16 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
expr: ExprId,
lhs_ty: Ty<'db>,
opt_rhs: Option<(ExprId, Ty<'db>)>,
- (opname, trait_did): (Symbol, Option<TraitId>),
+ (op_method, trait_did): (Option<FunctionId>, Option<TraitId>),
) -> Result<MethodCallee<'db>, Vec<NextSolverError<'db>>> {
- let Some(trait_did) = trait_did else {
+ let (Some(trait_did), Some(op_method)) = (trait_did, op_method) else {
// Bail if the operator trait is not defined.
return Err(vec![]);
};
debug!(
"lookup_op_method(lhs_ty={:?}, opname={:?}, trait_did={:?})",
- lhs_ty, opname, trait_did
+ lhs_ty, op_method, trait_did
);
let opt_rhs_ty = opt_rhs.map(|it| it.1);
@@ -304,8 +303,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
let method = self.table.lookup_method_for_operator(
cause,
- opname,
trait_did,
+ op_method,
lhs_ty,
opt_rhs_ty,
treat_opaques,
@@ -360,20 +359,20 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
}
}
- fn lang_item_for_bin_op(&self, op: BinaryOp) -> (Symbol, Option<TraitId>) {
- let (method_name, trait_lang_item) =
+ fn lang_item_for_bin_op(&self, op: BinaryOp) -> (Option<FunctionId>, Option<TraitId>) {
+ let (method, trait_lang_item) =
crate::lang_items::lang_items_for_bin_op(self.lang_items, op)
.expect("invalid operator provided");
- (method_name, trait_lang_item)
+ (method, trait_lang_item)
}
- fn lang_item_for_unop(&self, op: UnaryOp) -> (Symbol, Option<TraitId>) {
- let (method_name, trait_lang_item) = match op {
- UnaryOp::Not => (sym::not, self.lang_items.Not),
- UnaryOp::Neg => (sym::neg, self.lang_items.Neg),
+ fn lang_item_for_unop(&self, op: UnaryOp) -> (Option<FunctionId>, Option<TraitId>) {
+ let (method, trait_lang_item) = match op {
+ UnaryOp::Not => (self.lang_items.Not_not, self.lang_items.Not),
+ UnaryOp::Neg => (self.lang_items.Neg_neg, self.lang_items.Neg),
UnaryOp::Deref => panic!("Deref is not overloadable"),
};
- (method_name, trait_lang_item)
+ (method, trait_lang_item)
}
}
diff --git a/crates/hir-ty/src/infer/place_op.rs b/crates/hir-ty/src/infer/place_op.rs
index 968d793615..bbf047b8ba 100644
--- a/crates/hir-ty/src/infer/place_op.rs
+++ b/crates/hir-ty/src/infer/place_op.rs
@@ -1,7 +1,6 @@
//! Inference of *place operators*: deref and indexing (operators that create places, as opposed to values).
use hir_def::hir::ExprId;
-use intern::sym;
use rustc_ast_ir::Mutability;
use rustc_type_ir::inherent::{IntoKind, Ty as _};
use tracing::debug;
@@ -195,9 +194,9 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
) -> Option<InferOk<'db, MethodCallee<'db>>> {
debug!("try_overloaded_place_op({:?},{:?})", base_ty, op);
- let (Some(imm_tr), imm_op) = (match op {
- PlaceOp::Deref => (self.lang_items.Deref, sym::deref),
- PlaceOp::Index => (self.lang_items.Index, sym::index),
+ let (Some(imm_tr), Some(imm_op)) = (match op {
+ PlaceOp::Deref => (self.lang_items.Deref, self.lang_items.Deref_deref),
+ PlaceOp::Index => (self.lang_items.Index, self.lang_items.Index_index),
}) else {
// Bail if `Deref` or `Index` isn't defined.
return None;
@@ -208,8 +207,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
self.table.lookup_method_for_operator(
ObligationCause::new(expr),
- imm_op,
imm_tr,
+ imm_op,
base_ty,
opt_rhs_ty,
treat_opaques,
@@ -226,9 +225,9 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
debug!("try_mutable_overloaded_place_op({:?},{:?})", base_ty, op);
let lang_items = table.interner().lang_items();
- let (Some(mut_tr), mut_op) = (match op {
- PlaceOp::Deref => (lang_items.DerefMut, sym::deref_mut),
- PlaceOp::Index => (lang_items.IndexMut, sym::index_mut),
+ let (Some(mut_tr), Some(mut_op)) = (match op {
+ PlaceOp::Deref => (lang_items.DerefMut, lang_items.DerefMut_deref_mut),
+ PlaceOp::Index => (lang_items.IndexMut, lang_items.IndexMut_index_mut),
}) else {
// Bail if `DerefMut` or `IndexMut` isn't defined.
return None;
@@ -241,8 +240,8 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
let treat_opaques = TreatNotYetDefinedOpaques::AsInfer;
table.lookup_method_for_operator(
ObligationCause::new(expr),
- mut_op,
mut_tr,
+ mut_op,
base_ty,
opt_rhs_ty,
treat_opaques,
diff --git a/crates/hir-ty/src/lang_items.rs b/crates/hir-ty/src/lang_items.rs
index c8e15e2f9c..19d2d29c9e 100644
--- a/crates/hir-ty/src/lang_items.rs
+++ b/crates/hir-ty/src/lang_items.rs
@@ -1,53 +1,52 @@
//! Functions to detect special lang items
-use hir_def::{TraitId, lang_item::LangItems};
-use intern::{Symbol, sym};
+use hir_def::{FunctionId, TraitId, lang_item::LangItems};
pub fn lang_items_for_bin_op(
lang_items: &LangItems,
op: syntax::ast::BinaryOp,
-) -> Option<(Symbol, Option<TraitId>)> {
+) -> Option<(Option<FunctionId>, Option<TraitId>)> {
use syntax::ast::{ArithOp, BinaryOp, CmpOp, Ordering};
Some(match op {
BinaryOp::LogicOp(_) => return None,
BinaryOp::ArithOp(aop) => match aop {
- ArithOp::Add => (sym::add, lang_items.Add),
- ArithOp::Mul => (sym::mul, lang_items.Mul),
- ArithOp::Sub => (sym::sub, lang_items.Sub),
- ArithOp::Div => (sym::div, lang_items.Div),
- ArithOp::Rem => (sym::rem, lang_items.Rem),
- ArithOp::Shl => (sym::shl, lang_items.Shl),
- ArithOp::Shr => (sym::shr, lang_items.Shr),
- ArithOp::BitXor => (sym::bitxor, lang_items.BitXor),
- ArithOp::BitOr => (sym::bitor, lang_items.BitOr),
- ArithOp::BitAnd => (sym::bitand, lang_items.BitAnd),
+ ArithOp::Add => (lang_items.Add_add, lang_items.Add),
+ ArithOp::Mul => (lang_items.Mul_mul, lang_items.Mul),
+ ArithOp::Sub => (lang_items.Sub_sub, lang_items.Sub),
+ ArithOp::Div => (lang_items.Div_div, lang_items.Div),
+ ArithOp::Rem => (lang_items.Rem_rem, lang_items.Rem),
+ ArithOp::Shl => (lang_items.Shl_shl, lang_items.Shl),
+ ArithOp::Shr => (lang_items.Shr_shr, lang_items.Shr),
+ ArithOp::BitXor => (lang_items.BitXor_bitxor, lang_items.BitXor),
+ ArithOp::BitOr => (lang_items.BitOr_bitor, lang_items.BitOr),
+ ArithOp::BitAnd => (lang_items.BitAnd_bitand, lang_items.BitAnd),
},
BinaryOp::Assignment { op: Some(aop) } => match aop {
- ArithOp::Add => (sym::add_assign, lang_items.AddAssign),
- ArithOp::Mul => (sym::mul_assign, lang_items.MulAssign),
- ArithOp::Sub => (sym::sub_assign, lang_items.SubAssign),
- ArithOp::Div => (sym::div_assign, lang_items.DivAssign),
- ArithOp::Rem => (sym::rem_assign, lang_items.RemAssign),
- ArithOp::Shl => (sym::shl_assign, lang_items.ShlAssign),
- ArithOp::Shr => (sym::shr_assign, lang_items.ShrAssign),
- ArithOp::BitXor => (sym::bitxor_assign, lang_items.BitXorAssign),
- ArithOp::BitOr => (sym::bitor_assign, lang_items.BitOrAssign),
- ArithOp::BitAnd => (sym::bitand_assign, lang_items.BitAndAssign),
+ ArithOp::Add => (lang_items.AddAssign_add_assign, lang_items.AddAssign),
+ ArithOp::Mul => (lang_items.MulAssign_mul_assign, lang_items.MulAssign),
+ ArithOp::Sub => (lang_items.SubAssign_sub_assign, lang_items.SubAssign),
+ ArithOp::Div => (lang_items.DivAssign_div_assign, lang_items.DivAssign),
+ ArithOp::Rem => (lang_items.RemAssign_rem_assign, lang_items.RemAssign),
+ ArithOp::Shl => (lang_items.ShlAssign_shl_assign, lang_items.ShlAssign),
+ ArithOp::Shr => (lang_items.ShrAssign_shr_assign, lang_items.ShrAssign),
+ ArithOp::BitXor => (lang_items.BitXorAssign_bitxor_assign, lang_items.BitXorAssign),
+ ArithOp::BitOr => (lang_items.BitOrAssign_bitor_assign, lang_items.BitOrAssign),
+ ArithOp::BitAnd => (lang_items.BitAndAssign_bitand_assign, lang_items.BitAndAssign),
},
BinaryOp::CmpOp(cop) => match cop {
- CmpOp::Eq { negated: false } => (sym::eq, lang_items.PartialEq),
- CmpOp::Eq { negated: true } => (sym::ne, lang_items.PartialEq),
+ CmpOp::Eq { negated: false } => (lang_items.PartialEq_eq, lang_items.PartialEq),
+ CmpOp::Eq { negated: true } => (lang_items.PartialEq_ne, lang_items.PartialEq),
CmpOp::Ord { ordering: Ordering::Less, strict: false } => {
- (sym::le, lang_items.PartialOrd)
+ (lang_items.PartialOrd_le, lang_items.PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Less, strict: true } => {
- (sym::lt, lang_items.PartialOrd)
+ (lang_items.PartialOrd_lt, lang_items.PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Greater, strict: false } => {
- (sym::ge, lang_items.PartialOrd)
+ (lang_items.PartialOrd_ge, lang_items.PartialOrd)
}
CmpOp::Ord { ordering: Ordering::Greater, strict: true } => {
- (sym::gt, lang_items.PartialOrd)
+ (lang_items.PartialOrd_gt, lang_items.PartialOrd)
}
},
BinaryOp::Assignment { op: None } => return None,
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 5cb2a3d804..0c107460fa 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -573,10 +573,7 @@ pub fn callable_sig_from_fn_trait<'db>(
return None;
};
- let fn_once_trait = lang_items.FnOnce?;
- let output_assoc_type = fn_once_trait
- .trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
+ let output_assoc_type = lang_items.FnOnceOutput?;
let output_projection = Ty::new_alias(
interner,
AliasTy::new(
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 86477f2c0b..f8aac3e63a 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -25,7 +25,6 @@ use hir_def::{
signatures::{ConstSignature, FunctionSignature},
unstable_features::UnstableFeatures,
};
-use intern::Symbol;
use rustc_hash::{FxHashMap, FxHashSet};
use rustc_type_ir::{
TypeVisitableExt,
@@ -224,8 +223,8 @@ impl<'db> InferenceTable<'db> {
pub(super) fn lookup_method_for_operator(
&self,
cause: ObligationCause,
- method_name: Symbol,
trait_def_id: TraitId,
+ method_item: FunctionId,
self_ty: Ty<'db>,
opt_rhs_ty: Option<Ty<'db>>,
treat_opaques: TreatNotYetDefinedOpaques,
@@ -278,13 +277,6 @@ impl<'db> InferenceTable<'db> {
// Trait must have a method named `m_name` and it should not have
// type parameters or early-bound regions.
let interner = self.interner();
- // We use `Ident::with_dummy_span` since no built-in operator methods have
- // any macro-specific hygiene, so the span's context doesn't really matter.
- let Some(method_item) =
- trait_def_id.trait_items(self.db).method_by_name(&Name::new_symbol_root(method_name))
- else {
- panic!("expected associated item for operator trait")
- };
let def_id = method_item;
diff --git a/crates/hir-ty/src/method_resolution/confirm.rs b/crates/hir-ty/src/method_resolution/confirm.rs
index 821d737cf9..ffd65a58d8 100644
--- a/crates/hir-ty/src/method_resolution/confirm.rs
+++ b/crates/hir-ty/src/method_resolution/confirm.rs
@@ -2,7 +2,7 @@
//! is valid and registering all obligations.
use hir_def::{
- FunctionId, GenericDefId, GenericParamId, ItemContainerId, TraitId,
+ FunctionId, GenericDefId, GenericParamId, TraitId,
expr_store::path::{GenericArg as HirGenericArg, GenericArgs as HirGenericArgs},
hir::{ExprId, generics::GenericParamDataRef},
type_ref::TypeRefId,
@@ -575,9 +575,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> {
fn check_for_illegal_method_calls(&self) {
// Disallow calls to the method `drop` defined in the `Drop` trait.
- if let ItemContainerId::TraitId(trait_def_id) = self.candidate.loc(self.db()).container
- && self.ctx.lang_items.Drop.is_some_and(|drop_trait| drop_trait == trait_def_id)
- {
+ if self.ctx.lang_items.Drop_drop.is_some_and(|drop_fn| drop_fn == self.candidate) {
// FIXME: Report an error.
}
}
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 104b90eaf5..8701ad5be6 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -11,14 +11,13 @@ use hir_def::{
item_tree::FieldsShape,
lang_item::LangItems,
layout::{TagEncoding, Variants},
- resolver::{HasResolver, TypeNs, ValueNs},
+ resolver::{HasResolver, ValueNs},
signatures::{
EnumSignature, FunctionSignature, StaticFlags, StaticSignature, StructFlags,
StructSignature, TraitSignature,
},
};
-use hir_expand::{InFile, mod_path::path, name::Name};
-use intern::sym;
+use hir_expand::{InFile, mod_path::path};
use la_arena::ArenaMap;
use macros::GenericTypeVisitable;
use rustc_abi::{Size, TargetDataLayout};
@@ -692,15 +691,9 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
mir_or_dyn_index_cache: RefCell::new(Default::default()),
unused_locals_store: RefCell::new(Default::default()),
cached_ptr_size,
- cached_fn_trait_func: lang_items
- .Fn
- .and_then(|x| x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call))),
- cached_fn_mut_trait_func: lang_items.FnMut.and_then(|x| {
- x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_mut))
- }),
- cached_fn_once_trait_func: lang_items.FnOnce.and_then(|x| {
- x.trait_items(db).method_by_name(&Name::new_symbol_root(sym::call_once))
- }),
+ cached_fn_trait_func: lang_items.Fn_call,
+ cached_fn_mut_trait_func: lang_items.FnMut_call_mut,
+ cached_fn_once_trait_func: lang_items.FnOnce_call_once,
infcx,
})
}
@@ -3036,10 +3029,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
_metadata: &[u8],
span: MirSpan,
) -> Result<'db, ()> {
- let Some(drop_fn) = (|| {
- let drop_trait = self.lang_items().Drop?;
- drop_trait.trait_items(self.db).method_by_name(&Name::new_symbol_root(sym::drop))
- })() else {
+ let Some(drop_fn) = self.lang_items().Drop_drop else {
// in some tests we don't have drop trait in minicore, and
// we can ignore drop in them.
return Ok(());
@@ -3150,16 +3140,9 @@ pub fn render_const_using_debug_impl<'db>(
drop_flags: DropFlags::default(),
};
let data = evaluator.allocate_allocation_in_heap(locals, c)?;
+ let lang_items = evaluator.interner().lang_items();
let resolver = owner.resolver(db);
- let Some(TypeNs::TraitId(debug_trait)) = resolver.resolve_path_in_type_ns_fully(
- db,
- &hir_def::expr_store::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
- ) else {
- not_supported!("core::fmt::Debug not found");
- };
- let Some(debug_fmt_fn) =
- debug_trait.trait_items(db).method_by_name(&Name::new_symbol_root(sym::fmt))
- else {
+ let Some(debug_fmt_fn) = lang_items.Debug_fmt else {
not_supported!("core::fmt::Debug::fmt not found");
};
// a1 = &[""]
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index a0978bd6e8..284148873d 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -4,7 +4,6 @@
use std::cmp::{self, Ordering};
use hir_def::{attrs::AttrFlags, signatures::FunctionSignature};
-use hir_expand::name::Name;
use intern::sym;
use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, SliceLike, Ty as _};
use stdx::never;
@@ -1202,11 +1201,7 @@ impl<'a, 'db: 'a> Evaluator<'a, 'db> {
let addr = tuple.interval.addr.offset(offset);
args.push(IntervalAndTy::new(addr, field, self, locals)?);
}
- if let Some(target) = self.lang_items().FnOnce
- && let Some(def) = target
- .trait_items(self.db)
- .method_by_name(&Name::new_symbol_root(sym::call_once))
- {
+ if let Some(def) = self.lang_items().FnOnce_call_once {
self.exec_fn_trait(
def,
&args,
diff --git a/crates/hir-ty/src/mir/lower/as_place.rs b/crates/hir-ty/src/mir/lower/as_place.rs
index fb4a9add81..0f7fc9a18e 100644
--- a/crates/hir-ty/src/mir/lower/as_place.rs
+++ b/crates/hir-ty/src/mir/lower/as_place.rs
@@ -1,7 +1,6 @@
//! MIR lowering for places
use hir_def::FunctionId;
-use intern::sym;
use rustc_type_ir::inherent::{Region as _, Ty as _};
use super::*;
@@ -183,10 +182,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
expr_id.into(),
'b: {
if let Some((f, _)) = self.infer.method_resolution(expr_id)
- && let Some(deref_trait) = self.lang_items().DerefMut
- && let Some(deref_fn) = deref_trait
- .trait_items(self.db)
- .method_by_name(&Name::new_symbol_root(sym::deref_mut))
+ && let Some(deref_fn) = self.lang_items().DerefMut_deref_mut
{
break 'b deref_fn == f;
}
@@ -315,18 +311,12 @@ impl<'db> MirLowerCtx<'_, 'db> {
mutability: bool,
) -> Result<'db, Option<(Place, BasicBlockId)>> {
let lang_items = self.lang_items();
- let (mutability, trait_lang_item, trait_method_name, borrow_kind) = if !mutability {
- (
- Mutability::Not,
- lang_items.Deref,
- Name::new_symbol_root(sym::deref),
- BorrowKind::Shared,
- )
+ let (mutability, deref_fn, borrow_kind) = if !mutability {
+ (Mutability::Not, lang_items.Deref_deref, BorrowKind::Shared)
} else {
(
Mutability::Mut,
- lang_items.DerefMut,
- Name::new_symbol_root(sym::deref_mut),
+ lang_items.DerefMut_deref_mut,
BorrowKind::Mut { kind: MutBorrowKind::Default },
)
};
@@ -335,11 +325,7 @@ impl<'db> MirLowerCtx<'_, 'db> {
let target_ty_ref = Ty::new_ref(self.interner(), error_region, target_ty, mutability);
let ref_place: Place = self.temp(ty_ref, current, span)?.into();
self.push_assignment(current, ref_place, Rvalue::Ref(borrow_kind, place), span);
- let deref_trait = trait_lang_item.ok_or(MirLowerError::LangItemNotFound)?;
- let deref_fn = deref_trait
- .trait_items(self.db)
- .method_by_name(&trait_method_name)
- .ok_or(MirLowerError::LangItemNotFound)?;
+ let deref_fn = deref_fn.ok_or(MirLowerError::LangItemNotFound)?;
let deref_fn_op = Operand::const_zst(Ty::new_fn_def(
self.interner(),
CallableDefId::FunctionId(deref_fn).into(),
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 7ab9bca697..753ff246c2 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -5699,21 +5699,15 @@ impl<'db> Type<'db> {
/// This function is used in `.await` syntax completion.
pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
- let trait_ = lang_items
- .IntoFutureIntoFuture
- .and_then(|into_future_fn| {
- let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
- let into_future_trait = assoc_item.container_or_implemented_trait(db)?;
- Some(into_future_trait.id)
- })
- .or(lang_items.Future)?;
+ let (trait_, output_assoc_type) = lang_items
+ .IntoFuture
+ .zip(lang_items.IntoFutureOutput)
+ .or(lang_items.Future.zip(lang_items.FutureOutput))?;
if !traits::implements_trait_unique(self.ty, db, self.env, trait_) {
return None;
}
- let output_assoc_type =
- trait_.trait_items(db).associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
self.normalize_trait_assoc_type(db, &[], output_assoc_type.into())
}
@@ -5727,10 +5721,7 @@ impl<'db> Type<'db> {
/// This does **not** resolve `IntoIterator`, only `Iterator`.
pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
- let iterator_trait = lang_items.Iterator?;
- let iterator_item = iterator_trait
- .trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::Item))?;
+ let iterator_item = lang_items.IteratorItem?;
self.normalize_trait_assoc_type(db, &[], iterator_item.into())
}
@@ -5745,19 +5736,13 @@ impl<'db> Type<'db> {
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> {
let lang_items = hir_def::lang_item::lang_items(db, self.env.krate);
- let trait_ = lang_items.IntoIterIntoIter.and_then(|into_iter_fn| {
- let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?;
- let into_iter_trait = assoc_item.container_or_implemented_trait(db)?;
- Some(into_iter_trait.id)
- })?;
+ let trait_ = lang_items.IntoIterator?;
if !traits::implements_trait_unique(self.ty, db, self.env, trait_) {
return None;
}
- let into_iter_assoc_type = trait_
- .trait_items(db)
- .associated_type_by_name(&Name::new_symbol_root(sym::IntoIter))?;
+ let into_iter_assoc_type = lang_items.IntoIterIntoIterType?;
self.normalize_trait_assoc_type(db, &[], into_iter_assoc_type.into())
}
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 783faa9ac8..f8f8152219 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -10,7 +10,7 @@ use std::iter::{self, once};
use either::Either;
use hir_def::{
AdtId, AssocItemId, CallableDefId, ConstId, DefWithBodyId, ExpressionStoreOwnerId, FieldId,
- FunctionId, GenericDefId, LocalFieldId, ModuleDefId, StructId, TraitId, VariantId,
+ FunctionId, GenericDefId, LocalFieldId, ModuleDefId, StructId, VariantId,
expr_store::{
Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, HygieneId,
lower::ExprCollector,
@@ -706,35 +706,25 @@ impl<'db> SourceAnalyzer<'db> {
db: &'db dyn HirDatabase,
prefix_expr: &ast::PrefixExpr,
) -> Option<Function> {
+ let lang_items = self.lang_items(db);
let (_op_trait, op_fn) = match prefix_expr.op_kind()? {
ast::UnaryOp::Deref => {
// This can be either `Deref::deref` or `DerefMut::deref_mut`.
// Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
// use that result to find out which one it is.
- let (deref_trait, deref) = self.lang_trait_fn(
- db,
- self.lang_items(db).Deref,
- &Name::new_symbol_root(sym::deref),
- )?;
+ let (deref_trait, deref) = (lang_items.Deref?, lang_items.Deref_deref?);
self.infer()
.and_then(|infer| {
let expr = self.expr_id(prefix_expr.clone().into())?.as_expr()?;
let (func, _) = infer.method_resolution(expr)?;
- let (deref_mut_trait, deref_mut) = self.lang_trait_fn(
- db,
- self.lang_items(db).DerefMut,
- &Name::new_symbol_root(sym::deref_mut),
- )?;
+ let (deref_mut_trait, deref_mut) =
+ (lang_items.DerefMut?, lang_items.DerefMut_deref_mut?);
if func == deref_mut { Some((deref_mut_trait, deref_mut)) } else { None }
})
.unwrap_or((deref_trait, deref))
}
- ast::UnaryOp::Not => {
- self.lang_trait_fn(db, self.lang_items(db).Not, &Name::new_symbol_root(sym::not))?
- }
- ast::UnaryOp::Neg => {
- self.lang_trait_fn(db, self.lang_items(db).Neg, &Name::new_symbol_root(sym::neg))?
- }
+ ast::UnaryOp::Not => (lang_items.Not?, lang_items.Not_not?),
+ ast::UnaryOp::Neg => (lang_items.Neg?, lang_items.Neg_neg?),
};
let ty = self.ty_of_expr(prefix_expr.expr()?)?;
@@ -753,19 +743,16 @@ impl<'db> SourceAnalyzer<'db> {
) -> Option<Function> {
let base_ty = self.ty_of_expr(index_expr.base()?)?;
let index_ty = self.ty_of_expr(index_expr.index()?)?;
+ let lang_items = self.lang_items(db);
- let (_index_trait, index_fn) =
- self.lang_trait_fn(db, self.lang_items(db).Index, &Name::new_symbol_root(sym::index))?;
+ let (_index_trait, index_fn) = (lang_items.Index?, lang_items.Index_index?);
let op_fn = self
.infer()
.and_then(|infer| {
let expr = self.expr_id(index_expr.clone().into())?.as_expr()?;
let (func, _) = infer.method_resolution(expr)?;
- let (_index_mut_trait, index_mut_fn) = self.lang_trait_fn(
- db,
- self.lang_items(db).IndexMut,
- &Name::new_symbol_root(sym::index_mut),
- )?;
+ let (_index_mut_trait, index_mut_fn) =
+ (lang_items.IndexMut_index_mut?, lang_items.IndexMut_index_mut?);
if func == index_mut_fn { Some(index_mut_fn) } else { None }
})
.unwrap_or(index_fn);
@@ -784,10 +771,8 @@ impl<'db> SourceAnalyzer<'db> {
let lhs = self.ty_of_expr(binop_expr.lhs()?)?;
let rhs = self.ty_of_expr(binop_expr.rhs()?)?;
- let (_op_trait, op_fn) =
- lang_items_for_bin_op(self.lang_items(db), op).and_then(|(name, lang_item)| {
- self.lang_trait_fn(db, lang_item, &Name::new_symbol_root(name))
- })?;
+ let (op_fn, _op_trait) = lang_items_for_bin_op(self.lang_items(db), op)
+ .and_then(|(method, trait_)| method.zip(trait_))?;
// HACK: subst for `index()` coincides with that for `Index` because `index()` itself
// doesn't have any generic parameters, so we skip building another subst for `index()`.
let substs = GenericArgs::new_from_slice(&[lhs.into(), rhs.into()]);
@@ -1583,17 +1568,6 @@ impl<'db> SourceAnalyzer<'db> {
hir_def::lang_item::lang_items(db, self.resolver.krate())
}
- fn lang_trait_fn(
- &self,
- db: &'db dyn HirDatabase,
- lang_trait: Option<TraitId>,
- method_name: &Name,
- ) -> Option<(TraitId, FunctionId)> {
- let trait_id = lang_trait?;
- let fn_id = trait_id.trait_items(db).method_by_name(method_name)?;
- Some((trait_id, fn_id))
- }
-
fn ty_of_expr(&self, expr: ast::Expr) -> Option<Ty<'db>> {
self.infer()?.type_of_expr_or_pat(self.expr_id(expr)?)
}