Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22280 from ChayimFriedman2/cache-lang
perf: Cache more things that are related to lang items (paren traits, children/sibling assoc types/functions) but are not lang items themselves
| -rw-r--r-- | crates/hir-def/src/lang_item.rs | 168 | ||||
| -rw-r--r-- | crates/hir-ty/src/display.rs | 24 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/callee.rs | 32 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/op.rs | 27 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/place_op.rs | 17 | ||||
| -rw-r--r-- | crates/hir-ty/src/lang_items.rs | 57 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 5 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution.rs | 10 | ||||
| -rw-r--r-- | crates/hir-ty/src/method_resolution/confirm.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval.rs | 33 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval/shim.rs | 7 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/lower/as_place.rs | 24 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 29 | ||||
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 52 |
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)?) } |