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.rs188
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;
}