Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lang_item.rs')
| -rw-r--r-- | crates/hir-def/src/lang_item.rs | 188 |
1 files changed, 183 insertions, 5 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index 37d70b1e33..c2cbb9eda7 100644 --- a/crates/hir-def/src/lang_item.rs +++ b/crates/hir-def/src/lang_item.rs @@ -7,8 +7,8 @@ use intern::{Symbol, sym}; use stdx::impl_from; use crate::{ - AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, MacroId, - ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + AdtId, AssocItemId, AttrDefId, Crate, EnumId, EnumVariantId, FunctionId, ImplId, + ItemContainerId, MacroId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags, db::DefDatabase, nameres::{DefMap, assoc::TraitItems, crate_def_map, crate_local_def_map}, @@ -40,7 +40,7 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt let crate_def_map = crate_def_map(db, krate); - if !crate_def_map.is_unstable_feature_enabled(&sym::lang_items) { + if !crate_def_map.features().lang_items { return None; } @@ -102,6 +102,8 @@ pub fn crate_lang_items(db: &dyn DefDatabase, krate: Crate) -> Option<Box<LangIt lang_items.fill_non_lang_core_items(db, crate_def_map); } + lang_items.resolve_manually(db); + if lang_items.is_empty() { None } else { Some(Box::new(lang_items)) } } @@ -190,6 +192,122 @@ fn resolve_core_macro( current.scope.makro(&Name::new_symbol_root(name)) } +impl LangItems { + fn resolve_manually(&mut self, db: &dyn DefDatabase) { + 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())); + } + }; + 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(()) + })(); + } +} + #[salsa::tracked(returns(as_deref))] pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: Crate) -> Option<Box<[TraitId]>> { let mut traits = Vec::new(); @@ -221,6 +339,10 @@ macro_rules! language_item_table { @non_lang_core_macros: $( core::$($non_lang_macro_module:ident)::*, $non_lang_macro:ident, $non_lang_macro_field:ident; )* + + @resolve_manually: + + $( $resolve_manually:ident, $resolve_manually_type:ident; )* ) => { #[allow(non_snake_case)] // FIXME: Should we remove this? #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] @@ -235,6 +357,9 @@ macro_rules! language_item_table { $( pub $non_lang_macro_field: Option<MacroId>, )* + $( + pub $resolve_manually: Option<$resolve_manually_type>, + )* } impl LangItems { @@ -247,6 +372,7 @@ macro_rules! language_item_table { $( self.$lang_item = self.$lang_item.or(other.$lang_item); )* $( self.$non_lang_trait = self.$non_lang_trait.or(other.$non_lang_trait); )* $( self.$non_lang_macro_field = self.$non_lang_macro_field.or(other.$non_lang_macro_field); )* + $( self.$resolve_manually = self.$resolve_manually.or(other.$resolve_manually); )* } fn assign_lang_item(&mut self, name: Symbol, target: LangItemTarget) { @@ -365,9 +491,10 @@ language_item_table! { LangItems => Deref, sym::deref, TraitId; DerefMut, sym::deref_mut, TraitId; + DerefPure, sym::deref_pure, TraitId; DerefTarget, sym::deref_target, TypeAliasId; Receiver, sym::receiver, TraitId; - ReceiverTarget, sym::receiver_target, TypeAliasId; + ReceiverTarget, sym::receiver_target, TypeAliasId; Fn, sym::fn_, TraitId; FnMut, sym::fn_mut, TraitId; @@ -385,6 +512,7 @@ language_item_table! { LangItems => FnOnceOutput, sym::fn_once_output, TypeAliasId; Future, sym::future_trait, TraitId; + AsyncIterator, sym::async_iterator, TraitId; CoroutineState, sym::coroutine_state, EnumId; Coroutine, sym::coroutine, TraitId; CoroutineReturn, sym::coroutine_return, TypeAliasId; @@ -494,7 +622,6 @@ language_item_table! { LangItems => IteratorNext, sym::next, FunctionId; Iterator, sym::iterator, TraitId; FusedIterator, sym::fused_iterator, TraitId; - AsyncIterator, sym::async_iterator, TraitId; PinNewUnchecked, sym::new_unchecked, FunctionId; @@ -537,4 +664,55 @@ language_item_table! { LangItems => core::marker, CoercePointee, CoercePointeeDerive; core::marker, Copy, CopyDerive; core::clone, Clone, CloneDerive; + + @resolve_manually: + + 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; } |