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.rs33
1 files changed, 15 insertions, 18 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..a76586f0c 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -19,10 +19,9 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id,
23 utils::all_super_traits, 22 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 23 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, 24 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind,
26 TypeWalk, 25 TypeWalk,
27}; 26};
28 27
@@ -47,7 +46,7 @@ impl TyFingerprint {
47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 46 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
48 /// `impl &S`. Hence, this will return `None` for reference types and such. 47 /// `impl &S`. Hence, this will return `None` for reference types and such.
49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 48 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
50 let fp = match *ty.interned(&Interner) { 49 let fp = match *ty.kind(&Interner) {
51 TyKind::Str => TyFingerprint::Str, 50 TyKind::Str => TyFingerprint::Str,
52 TyKind::Never => TyFingerprint::Never, 51 TyKind::Never => TyFingerprint::Never,
53 TyKind::Slice(..) => TyFingerprint::Slice, 52 TyKind::Slice(..) => TyFingerprint::Slice,
@@ -243,7 +242,7 @@ impl Ty {
243 242
244 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 243 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
245 244
246 let lang_item_targets = match self.interned(&Interner) { 245 let lang_item_targets = match self.kind(&Interner) {
247 TyKind::Adt(AdtId(def_id), _) => { 246 TyKind::Adt(AdtId(def_id), _) => {
248 return mod_to_crate_ids(def_id.module(db.upcast())); 247 return mod_to_crate_ids(def_id.module(db.upcast()));
249 } 248 }
@@ -563,7 +562,7 @@ fn iterate_trait_method_candidates(
563 // if ty is `dyn Trait`, the trait doesn't need to be in scope 562 // if ty is `dyn Trait`, the trait doesn't need to be in scope
564 let inherent_trait = 563 let inherent_trait =
565 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 564 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
566 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { 565 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
567 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 566 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
568 env.traits_in_scope_from_clauses(&self_ty.value) 567 env.traits_in_scope_from_clauses(&self_ty.value)
569 .flat_map(|t| all_super_traits(db.upcast(), t)) 568 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -675,7 +674,7 @@ fn is_valid_candidate(
675 } 674 }
676 } 675 }
677 if let Some(receiver_ty) = receiver_ty { 676 if let Some(receiver_ty) = receiver_ty {
678 if !data.has_self_param { 677 if !data.has_self_param() {
679 return false; 678 return false;
680 } 679 }
681 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 680 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
@@ -710,7 +709,7 @@ pub(crate) fn inherent_impl_substs(
710) -> Option<Substitution> { 709) -> Option<Substitution> {
711 // we create a var for each type parameter of the impl; we need to keep in 710 // we create a var for each type parameter of the impl; we need to keep in
712 // mind here that `self_ty` might have vars of its own 711 // mind here that `self_ty` might have vars of its own
713 let vars = Substitution::build_for_def(db, impl_id) 712 let vars = TyBuilder::subst_for_def(db, impl_id)
714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 713 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
715 .build(); 714 .build();
716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 715 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
@@ -720,7 +719,7 @@ pub(crate) fn inherent_impl_substs(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 719 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 720 UniverseIndex::ROOT,
722 )) 721 ))
723 .take(vars.len()), 722 .take(vars.len(&Interner)),
724 ); 723 );
725 let tys = Canonical { 724 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 725 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
@@ -732,7 +731,8 @@ pub(crate) fn inherent_impl_substs(
732 // Unknown. I think this can only really happen if self_ty contained 731 // Unknown. I think this can only really happen if self_ty contained
733 // Unknown, and in that case we want the result to contain Unknown in those 732 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 733 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 734 substs
735 .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner)))
736} 736}
737 737
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -740,7 +740,7 @@ pub(crate) fn inherent_impl_substs(
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 741 s.fold_binders(
742 &mut |ty, binders| { 742 &mut |ty, binders| {
743 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 743 if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
745 TyKind::Unknown.intern(&Interner) 745 TyKind::Unknown.intern(&Interner)
746 } else { 746 } else {
@@ -760,13 +760,13 @@ fn transform_receiver_ty(
760 self_ty: &Canonical<Ty>, 760 self_ty: &Canonical<Ty>,
761) -> Option<Ty> { 761) -> Option<Ty> {
762 let substs = match function_id.lookup(db.upcast()).container { 762 let substs = match function_id.lookup(db.upcast()).container {
763 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) 763 AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
764 .push(self_ty.value.clone()) 764 .push(self_ty.value.clone())
765 .fill_with_unknown() 765 .fill_with_unknown()
766 .build(), 766 .build(),
767 AssocContainerId::ImplId(impl_id) => { 767 AssocContainerId::ImplId(impl_id) => {
768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
769 Substitution::build_for_def(db, function_id) 769 TyBuilder::subst_for_def(db, function_id)
770 .use_parent_substs(&impl_substs) 770 .use_parent_substs(&impl_substs)
771 .fill_with_unknown() 771 .fill_with_unknown()
772 .build() 772 .build()
@@ -812,7 +812,7 @@ fn generic_implements_goal(
812 self_ty: Canonical<Ty>, 812 self_ty: Canonical<Ty>,
813) -> Canonical<InEnvironment<super::DomainGoal>> { 813) -> Canonical<InEnvironment<super::DomainGoal>> {
814 let mut kinds = self_ty.binders.interned().to_vec(); 814 let mut kinds = self_ty.binders.interned().to_vec();
815 let substs = super::Substitution::build_for_def(db, trait_) 815 let trait_ref = TyBuilder::trait_ref(db, trait_)
816 .push(self_ty.value) 816 .push(self_ty.value)
817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
818 .build(); 818 .build();
@@ -821,9 +821,8 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 822 UniverseIndex::ROOT,
823 )) 823 ))
824 .take(substs.len() - 1), 824 .take(trait_ref.substitution.len(&Interner) - 1),
825 ); 825 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 826 let obligation = trait_ref.cast(&Interner);
828 Canonical { 827 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 828 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
@@ -838,9 +837,7 @@ fn autoderef_method_receiver(
838) -> Vec<Canonical<Ty>> { 837) -> Vec<Canonical<Ty>> {
839 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 838 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
840 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 839 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
841 if let Some(TyKind::Array(parameters)) = 840 if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) {
842 deref_chain.last().map(|ty| ty.value.interned(&Interner))
843 {
844 let kinds = deref_chain.last().unwrap().binders.clone(); 841 let kinds = deref_chain.last().unwrap().binders.clone();
845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 842 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
846 deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) 843 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })