aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r--crates/hir_ty/src/method_resolution.rs126
1 files changed, 71 insertions, 55 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 66d8de959..087b67935 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -7,8 +7,8 @@ use std::{iter, sync::Arc};
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use hir_def::{ 9use hir_def::{
10 lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, 10 lang_item::LangItemTarget, type_ref::Mutability, AdtId, AssocContainerId, AssocItemId,
11 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, 11 FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId,
12}; 12};
13use hir_expand::name::Name; 13use hir_expand::name::Name;
14use rustc_hash::{FxHashMap, FxHashSet}; 14use rustc_hash::{FxHashMap, FxHashSet};
@@ -18,15 +18,24 @@ use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 primitive::{self, FloatTy, IntTy, UintTy}, 19 primitive::{self, FloatTy, IntTy, UintTy},
20 utils::all_super_traits, 20 utils::all_super_traits,
21 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, 21 Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, TraitRef, Ty,
22 TraitRef, Ty, TyKind, TypeCtor, TypeWalk, 22 TyKind, TypeWalk,
23}; 23};
24 24
25/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
27pub enum TyFingerprint { 27pub enum TyFingerprint {
28 Apply(TypeCtor), 28 Str,
29 Slice,
30 Array,
31 Never,
32 RawPtr(Mutability),
33 Scalar(Scalar),
34 Adt(AdtId),
29 Dyn(TraitId), 35 Dyn(TraitId),
36 Tuple { cardinality: u16 },
37 ForeignType(TypeAliasId),
38 FnPtr { num_args: u16, is_varargs: bool },
30} 39}
31 40
32impl TyFingerprint { 41impl TyFingerprint {
@@ -34,32 +43,44 @@ impl TyFingerprint {
34 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 43 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
35 /// `impl &S`. Hence, this will return `None` for reference types and such. 44 /// `impl &S`. Hence, this will return `None` for reference types and such.
36 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 45 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
37 match ty { 46 let fp = match ty {
38 Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), 47 &Ty::Str => TyFingerprint::Str,
39 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), 48 &Ty::Never => TyFingerprint::Never,
40 _ => None, 49 &Ty::Slice(..) => TyFingerprint::Slice,
41 } 50 &Ty::Array(..) => TyFingerprint::Array,
51 &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar),
52 &Ty::Adt(adt, _) => TyFingerprint::Adt(adt),
53 &Ty::Tuple { cardinality: u16, .. } => TyFingerprint::Tuple { cardinality: u16 },
54 &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability),
55 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
56 &Ty::FnPtr { num_args, is_varargs, .. } => {
57 TyFingerprint::FnPtr { num_args, is_varargs }
58 }
59 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
60 _ => return None,
61 };
62 Some(fp)
42 } 63 }
43} 64}
44 65
45pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 66pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
46 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), 67 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
47 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), 68 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
48 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), 69 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
49 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), 70 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
50 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), 71 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
51 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), 72 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
52 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), 73 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
53 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), 74 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
54 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), 75 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
55 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), 76 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
56 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), 77 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
57 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), 78 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
58]; 79];
59 80
60pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 81pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
61 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), 82 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
62 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), 83 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
63]; 84];
64 85
65/// Trait impls defined or available in some crate. 86/// Trait impls defined or available in some crate.
@@ -211,32 +232,29 @@ impl Ty {
211 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 232 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
212 233
213 let lang_item_targets = match self { 234 let lang_item_targets = match self {
214 Ty::Apply(a_ty) => match a_ty.ctor { 235 Ty::Adt(def_id, _) => {
215 TypeCtor::Adt(def_id) => { 236 return mod_to_crate_ids(def_id.module(db.upcast()));
216 return mod_to_crate_ids(def_id.module(db.upcast())); 237 }
217 } 238 Ty::ForeignType(type_alias_id, _) => {
218 TypeCtor::ForeignType(type_alias_id) => { 239 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
219 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 240 }
220 } 241 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
221 TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 242 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"),
222 TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), 243 Ty::Scalar(Scalar::Float(f)) => match f {
223 TypeCtor::Scalar(Scalar::Float(f)) => match f { 244 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
224 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 245 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
225 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 246 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
226 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
227 },
228 TypeCtor::Scalar(Scalar::Int(t)) => {
229 lang_item_crate!(primitive::int_ty_to_string(t))
230 }
231 TypeCtor::Scalar(Scalar::Uint(t)) => {
232 lang_item_crate!(primitive::uint_ty_to_string(t))
233 }
234 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
235 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
236 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
237 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
238 _ => return None,
239 }, 247 },
248 &Ty::Scalar(Scalar::Int(t)) => {
249 lang_item_crate!(primitive::int_ty_to_string(t))
250 }
251 &Ty::Scalar(Scalar::Uint(t)) => {
252 lang_item_crate!(primitive::uint_ty_to_string(t))
253 }
254 Ty::Str => lang_item_crate!("str_alloc", "str"),
255 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
256 Ty::RawPtr(Mutability::Shared, _) => lang_item_crate!("const_ptr"),
257 Ty::RawPtr(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
240 Ty::Dyn(_) => { 258 Ty::Dyn(_) => {
241 return self.dyn_trait().and_then(|trait_| { 259 return self.dyn_trait().and_then(|trait_| {
242 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 260 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
@@ -413,7 +431,7 @@ fn iterate_method_candidates_with_autoref(
413 } 431 }
414 let refed = Canonical { 432 let refed = Canonical {
415 kinds: deref_chain[0].kinds.clone(), 433 kinds: deref_chain[0].kinds.clone(),
416 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), 434 value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())),
417 }; 435 };
418 if iterate_method_candidates_by_receiver( 436 if iterate_method_candidates_by_receiver(
419 &refed, 437 &refed,
@@ -429,7 +447,7 @@ fn iterate_method_candidates_with_autoref(
429 } 447 }
430 let ref_muted = Canonical { 448 let ref_muted = Canonical {
431 kinds: deref_chain[0].kinds.clone(), 449 kinds: deref_chain[0].kinds.clone(),
432 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), 450 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())),
433 }; 451 };
434 if iterate_method_candidates_by_receiver( 452 if iterate_method_candidates_by_receiver(
435 &ref_muted, 453 &ref_muted,
@@ -756,11 +774,9 @@ fn autoderef_method_receiver(
756) -> Vec<Canonical<Ty>> { 774) -> Vec<Canonical<Ty>> {
757 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 775 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
758 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 776 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
759 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = 777 if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) {
760 deref_chain.last().map(|ty| &ty.value)
761 {
762 let kinds = deref_chain.last().unwrap().kinds.clone(); 778 let kinds = deref_chain.last().unwrap().kinds.clone();
763 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 779 let unsized_ty = Ty::Slice(parameters.clone());
764 deref_chain.push(Canonical { value: unsized_ty, kinds }) 780 deref_chain.push(Canonical { value: unsized_ty, kinds })
765 } 781 }
766 deref_chain 782 deref_chain