diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index d57c6de70..f9877e760 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -19,8 +19,8 @@ use crate::{ | |||
19 | db::HirDatabase, | 19 | db::HirDatabase, |
20 | primitive::{self, FloatTy, IntTy, UintTy}, | 20 | primitive::{self, FloatTy, IntTy, UintTy}, |
21 | utils::all_super_traits, | 21 | utils::all_super_traits, |
22 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, | 22 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Interner, Scalar, Substs, |
23 | TraitEnvironment, TraitRef, Ty, TypeWalk, | 23 | TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | /// This is used as a key for indexing impls. | 26 | /// This is used as a key for indexing impls. |
@@ -44,18 +44,20 @@ impl TyFingerprint { | |||
44 | /// 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 |
45 | /// `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. |
46 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 46 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
47 | let fp = match ty { | 47 | let fp = match *ty.interned(&Interner) { |
48 | &Ty::Str => TyFingerprint::Str, | 48 | TyKind::Str => TyFingerprint::Str, |
49 | &Ty::Never => TyFingerprint::Never, | 49 | TyKind::Never => TyFingerprint::Never, |
50 | &Ty::Slice(..) => TyFingerprint::Slice, | 50 | TyKind::Slice(..) => TyFingerprint::Slice, |
51 | &Ty::Array(..) => TyFingerprint::Array, | 51 | TyKind::Array(..) => TyFingerprint::Array, |
52 | &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), | 52 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), |
53 | &Ty::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), | 53 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), |
54 | &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | 54 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), |
55 | &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | 55 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), |
56 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | 56 | TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), |
57 | &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), | 57 | TyKind::Function(FnPointer { num_args, sig, .. }) => { |
58 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | 58 | TyFingerprint::FnPtr(num_args, sig) |
59 | } | ||
60 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
59 | _ => return None, | 61 | _ => return None, |
60 | }; | 62 | }; |
61 | Some(fp) | 63 | Some(fp) |
@@ -230,31 +232,31 @@ impl Ty { | |||
230 | 232 | ||
231 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 233 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
232 | 234 | ||
233 | let lang_item_targets = match self { | 235 | let lang_item_targets = match self.interned(&Interner) { |
234 | Ty::Adt(AdtId(def_id), _) => { | 236 | TyKind::Adt(AdtId(def_id), _) => { |
235 | return mod_to_crate_ids(def_id.module(db.upcast())); | 237 | return mod_to_crate_ids(def_id.module(db.upcast())); |
236 | } | 238 | } |
237 | Ty::ForeignType(type_alias_id) => { | 239 | TyKind::ForeignType(type_alias_id) => { |
238 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); | 240 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); |
239 | } | 241 | } |
240 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 242 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
241 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), | 243 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
242 | Ty::Scalar(Scalar::Float(f)) => match f { | 244 | TyKind::Scalar(Scalar::Float(f)) => match f { |
243 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 245 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
244 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 246 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
245 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 247 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
246 | }, | 248 | }, |
247 | &Ty::Scalar(Scalar::Int(t)) => { | 249 | &TyKind::Scalar(Scalar::Int(t)) => { |
248 | lang_item_crate!(primitive::int_ty_to_string(t)) | 250 | lang_item_crate!(primitive::int_ty_to_string(t)) |
249 | } | 251 | } |
250 | &Ty::Scalar(Scalar::Uint(t)) => { | 252 | &TyKind::Scalar(Scalar::Uint(t)) => { |
251 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 253 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
252 | } | 254 | } |
253 | Ty::Str => lang_item_crate!("str_alloc", "str"), | 255 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
254 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 256 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
255 | Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 257 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
256 | Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 258 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
257 | Ty::Dyn(_) => { | 259 | TyKind::Dyn(_) => { |
258 | return self.dyn_trait().and_then(|trait_| { | 260 | return self.dyn_trait().and_then(|trait_| { |
259 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 261 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
260 | }); | 262 | }); |
@@ -430,7 +432,8 @@ fn iterate_method_candidates_with_autoref( | |||
430 | } | 432 | } |
431 | let refed = Canonical { | 433 | let refed = Canonical { |
432 | kinds: deref_chain[0].kinds.clone(), | 434 | kinds: deref_chain[0].kinds.clone(), |
433 | value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), | 435 | value: TyKind::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())) |
436 | .intern(&Interner), | ||
434 | }; | 437 | }; |
435 | if iterate_method_candidates_by_receiver( | 438 | if iterate_method_candidates_by_receiver( |
436 | &refed, | 439 | &refed, |
@@ -446,7 +449,8 @@ fn iterate_method_candidates_with_autoref( | |||
446 | } | 449 | } |
447 | let ref_muted = Canonical { | 450 | let ref_muted = Canonical { |
448 | kinds: deref_chain[0].kinds.clone(), | 451 | kinds: deref_chain[0].kinds.clone(), |
449 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), | 452 | value: TyKind::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())) |
453 | .intern(&Interner), | ||
450 | }; | 454 | }; |
451 | if iterate_method_candidates_by_receiver( | 455 | if iterate_method_candidates_by_receiver( |
452 | &ref_muted, | 456 | &ref_muted, |
@@ -526,7 +530,7 @@ fn iterate_trait_method_candidates( | |||
526 | // if ty is `dyn Trait`, the trait doesn't need to be in scope | 530 | // if ty is `dyn Trait`, the trait doesn't need to be in scope |
527 | let inherent_trait = | 531 | let inherent_trait = |
528 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); | 532 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); |
529 | let env_traits = if let Ty::Placeholder(_) = self_ty.value { | 533 | let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { |
530 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | 534 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope |
531 | env.traits_in_scope_from_clauses(&self_ty.value) | 535 | env.traits_in_scope_from_clauses(&self_ty.value) |
532 | .flat_map(|t| all_super_traits(db.upcast(), t)) | 536 | .flat_map(|t| all_super_traits(db.upcast(), t)) |
@@ -679,13 +683,13 @@ pub(crate) fn inherent_impl_substs( | |||
679 | } | 683 | } |
680 | 684 | ||
681 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 685 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
682 | /// num_vars_to_keep) by `Ty::Unknown`. | 686 | /// num_vars_to_keep) by `TyKind::Unknown`. |
683 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { | 687 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { |
684 | s.fold_binders( | 688 | s.fold_binders( |
685 | &mut |ty, binders| { | 689 | &mut |ty, binders| { |
686 | if let Ty::BoundVar(bound) = &ty { | 690 | if let TyKind::BoundVar(bound) = ty.interned(&Interner) { |
687 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 691 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { |
688 | Ty::Unknown | 692 | TyKind::Unknown.intern(&Interner) |
689 | } else { | 693 | } else { |
690 | ty | 694 | ty |
691 | } | 695 | } |
@@ -772,9 +776,11 @@ fn autoderef_method_receiver( | |||
772 | ) -> Vec<Canonical<Ty>> { | 776 | ) -> Vec<Canonical<Ty>> { |
773 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 777 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
774 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 778 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
775 | if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { | 779 | if let Some(TyKind::Array(parameters)) = |
780 | deref_chain.last().map(|ty| ty.value.interned(&Interner)) | ||
781 | { | ||
776 | let kinds = deref_chain.last().unwrap().kinds.clone(); | 782 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
777 | let unsized_ty = Ty::Slice(parameters.clone()); | 783 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
778 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 784 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
779 | } | 785 | } |
780 | deref_chain | 786 | deref_chain |