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.rs167
1 files changed, 74 insertions, 93 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index b3d1fe9a4..f301a8477 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,12 +6,10 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::Mutability;
9use hir_def::{ 10use hir_def::{
10 builtin_type::{IntBitness, Signedness}, 11 lang_item::LangItemTarget, AdtId, AssocContainerId, AssocItemId, FunctionId, GenericDefId,
11 lang_item::LangItemTarget, 12 HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId,
12 type_ref::Mutability,
13 AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId,
14 TraitId,
15}; 13};
16use hir_expand::name::Name; 14use hir_expand::name::Name;
17use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
@@ -19,17 +17,26 @@ use rustc_hash::{FxHashMap, FxHashSet};
19use crate::{ 17use crate::{
20 autoderef, 18 autoderef,
21 db::HirDatabase, 19 db::HirDatabase,
22 primitive::{FloatBitness, FloatTy, IntTy}, 20 primitive::{self, FloatTy, IntTy, UintTy},
23 utils::all_super_traits, 21 utils::all_super_traits,
24 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, 22 Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment,
25 TyKind, TypeCtor, TypeWalk, 23 TraitRef, Ty, TypeWalk,
26}; 24};
27 25
28/// This is used as a key for indexing impls. 26/// This is used as a key for indexing impls.
29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 27#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30pub enum TyFingerprint { 28pub enum TyFingerprint {
31 Apply(TypeCtor), 29 Str,
30 Slice,
31 Array,
32 Never,
33 RawPtr(Mutability),
34 Scalar(Scalar),
35 Adt(AdtId),
32 Dyn(TraitId), 36 Dyn(TraitId),
37 Tuple(usize),
38 ForeignType(TypeAliasId),
39 FnPtr(usize, FnSig),
33} 40}
34 41
35impl TyFingerprint { 42impl TyFingerprint {
@@ -37,68 +44,42 @@ impl TyFingerprint {
37 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 44 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
38 /// `impl &S`. Hence, this will return `None` for reference types and such. 45 /// `impl &S`. Hence, this will return `None` for reference types and such.
39 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 46 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
40 match ty { 47 let fp = match ty {
41 Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), 48 &Ty::Str => TyFingerprint::Str,
42 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), 49 &Ty::Never => TyFingerprint::Never,
43 _ => None, 50 &Ty::Slice(..) => TyFingerprint::Slice,
44 } 51 &Ty::Array(..) => TyFingerprint::Array,
52 &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar),
53 &Ty::Adt(adt, _) => TyFingerprint::Adt(adt),
54 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
55 &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability),
56 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
57 &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig),
58 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
59 _ => return None,
60 };
61 Some(fp)
45 } 62 }
46} 63}
47 64
48pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 65pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
49 TyFingerprint::Apply(TypeCtor::Int(IntTy { 66 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
50 signedness: Signedness::Unsigned, 67 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
51 bitness: IntBitness::X8, 68 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
52 })), 69 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
53 TyFingerprint::Apply(TypeCtor::Int(IntTy { 70 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
54 signedness: Signedness::Unsigned, 71 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
55 bitness: IntBitness::X16, 72 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
56 })), 73 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
57 TyFingerprint::Apply(TypeCtor::Int(IntTy { 74 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
58 signedness: Signedness::Unsigned, 75 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
59 bitness: IntBitness::X32, 76 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
60 })), 77 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
61 TyFingerprint::Apply(TypeCtor::Int(IntTy {
62 signedness: Signedness::Unsigned,
63 bitness: IntBitness::X64,
64 })),
65 TyFingerprint::Apply(TypeCtor::Int(IntTy {
66 signedness: Signedness::Unsigned,
67 bitness: IntBitness::X128,
68 })),
69 TyFingerprint::Apply(TypeCtor::Int(IntTy {
70 signedness: Signedness::Unsigned,
71 bitness: IntBitness::Xsize,
72 })),
73 TyFingerprint::Apply(TypeCtor::Int(IntTy {
74 signedness: Signedness::Signed,
75 bitness: IntBitness::X8,
76 })),
77 TyFingerprint::Apply(TypeCtor::Int(IntTy {
78 signedness: Signedness::Signed,
79 bitness: IntBitness::X16,
80 })),
81 TyFingerprint::Apply(TypeCtor::Int(IntTy {
82 signedness: Signedness::Signed,
83 bitness: IntBitness::X32,
84 })),
85 TyFingerprint::Apply(TypeCtor::Int(IntTy {
86 signedness: Signedness::Signed,
87 bitness: IntBitness::X64,
88 })),
89 TyFingerprint::Apply(TypeCtor::Int(IntTy {
90 signedness: Signedness::Signed,
91 bitness: IntBitness::X128,
92 })),
93 TyFingerprint::Apply(TypeCtor::Int(IntTy {
94 signedness: Signedness::Signed,
95 bitness: IntBitness::Xsize,
96 })),
97]; 78];
98 79
99pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 80pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
100 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), 81 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
101 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), 82 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
102]; 83];
103 84
104/// Trait impls defined or available in some crate. 85/// Trait impls defined or available in some crate.
@@ -250,27 +231,29 @@ impl Ty {
250 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 231 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
251 232
252 let lang_item_targets = match self { 233 let lang_item_targets = match self {
253 Ty::Apply(a_ty) => match a_ty.ctor { 234 Ty::Adt(def_id, _) => {
254 TypeCtor::Adt(def_id) => { 235 return mod_to_crate_ids(def_id.module(db.upcast()));
255 return mod_to_crate_ids(def_id.module(db.upcast())); 236 }
256 } 237 Ty::ForeignType(type_alias_id) => {
257 TypeCtor::ForeignType(type_alias_id) => { 238 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
258 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 239 }
259 } 240 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
260 TypeCtor::Bool => lang_item_crate!("bool"), 241 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"),
261 TypeCtor::Char => lang_item_crate!("char"), 242 Ty::Scalar(Scalar::Float(f)) => match f {
262 TypeCtor::Float(f) => match f.bitness { 243 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
263 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 244 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
264 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 245 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
265 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
266 },
267 TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()),
268 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
269 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
270 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
271 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
272 _ => return None,
273 }, 246 },
247 &Ty::Scalar(Scalar::Int(t)) => {
248 lang_item_crate!(primitive::int_ty_to_string(t))
249 }
250 &Ty::Scalar(Scalar::Uint(t)) => {
251 lang_item_crate!(primitive::uint_ty_to_string(t))
252 }
253 Ty::Str => lang_item_crate!("str_alloc", "str"),
254 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
255 Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
256 Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
274 Ty::Dyn(_) => { 257 Ty::Dyn(_) => {
275 return self.dyn_trait().and_then(|trait_| { 258 return self.dyn_trait().and_then(|trait_| {
276 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 259 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
@@ -447,7 +430,7 @@ fn iterate_method_candidates_with_autoref(
447 } 430 }
448 let refed = Canonical { 431 let refed = Canonical {
449 kinds: deref_chain[0].kinds.clone(), 432 kinds: deref_chain[0].kinds.clone(),
450 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), 433 value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())),
451 }; 434 };
452 if iterate_method_candidates_by_receiver( 435 if iterate_method_candidates_by_receiver(
453 &refed, 436 &refed,
@@ -463,7 +446,7 @@ fn iterate_method_candidates_with_autoref(
463 } 446 }
464 let ref_muted = Canonical { 447 let ref_muted = Canonical {
465 kinds: deref_chain[0].kinds.clone(), 448 kinds: deref_chain[0].kinds.clone(),
466 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), 449 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())),
467 }; 450 };
468 if iterate_method_candidates_by_receiver( 451 if iterate_method_candidates_by_receiver(
469 &ref_muted, 452 &ref_muted,
@@ -685,7 +668,7 @@ pub(crate) fn inherent_impl_substs(
685 .build(); 668 .build();
686 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 669 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
687 let mut kinds = self_ty.kinds.to_vec(); 670 let mut kinds = self_ty.kinds.to_vec();
688 kinds.extend(iter::repeat(TyKind::General).take(vars.len())); 671 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len()));
689 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 672 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) };
690 let substs = super::infer::unify(&tys); 673 let substs = super::infer::unify(&tys);
691 // We only want the substs for the vars we added, not the ones from self_ty. 674 // We only want the substs for the vars we added, not the ones from self_ty.
@@ -701,7 +684,7 @@ pub(crate) fn inherent_impl_substs(
701fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 684fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
702 s.fold_binders( 685 s.fold_binders(
703 &mut |ty, binders| { 686 &mut |ty, binders| {
704 if let Ty::Bound(bound) = &ty { 687 if let Ty::BoundVar(bound) = &ty {
705 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 688 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
706 Ty::Unknown 689 Ty::Unknown
707 } else { 690 } else {
@@ -777,7 +760,7 @@ fn generic_implements_goal(
777 .push(self_ty.value) 760 .push(self_ty.value)
778 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 761 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
779 .build(); 762 .build();
780 kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); 763 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
781 let trait_ref = TraitRef { trait_, substs }; 764 let trait_ref = TraitRef { trait_, substs };
782 let obligation = super::Obligation::Trait(trait_ref); 765 let obligation = super::Obligation::Trait(trait_ref);
783 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 766 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
@@ -790,11 +773,9 @@ fn autoderef_method_receiver(
790) -> Vec<Canonical<Ty>> { 773) -> Vec<Canonical<Ty>> {
791 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 774 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
792 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 775 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
793 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = 776 if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) {
794 deref_chain.last().map(|ty| &ty.value)
795 {
796 let kinds = deref_chain.last().unwrap().kinds.clone(); 777 let kinds = deref_chain.last().unwrap().kinds.clone();
797 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 778 let unsized_ty = Ty::Slice(parameters.clone());
798 deref_chain.push(Canonical { value: unsized_ty, kinds }) 779 deref_chain.push(Canonical { value: unsized_ty, kinds })
799 } 780 }
800 deref_chain 781 deref_chain