diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 126 |
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}; | |||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use hir_def::{ | 9 | use 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 | }; |
13 | use hir_expand::name::Name; | 13 | use hir_expand::name::Name; |
14 | use rustc_hash::{FxHashMap, FxHashSet}; | 14 | use 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)] |
27 | pub enum TyFingerprint { | 27 | pub 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 | ||
32 | impl TyFingerprint { | 41 | impl 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 | ||
45 | pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ | 66 | pub(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 | ||
60 | pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ | 81 | pub(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 |