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.rs53
1 files changed, 36 insertions, 17 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 54192ec30..84d9a1e18 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability}; 9use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12 ImplId, Lookup, ModuleId, TraitId, 12 ImplId, Lookup, ModuleId, TraitId,
@@ -21,8 +21,9 @@ use crate::{
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id, 22 to_chalk_trait_id,
23 utils::all_super_traits, 23 utils::all_super_traits,
24 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind,
26 TypeWalk,
26}; 27};
27 28
28/// This is used as a key for indexing impls. 29/// This is used as a key for indexing impls.
@@ -380,7 +381,7 @@ fn iterate_method_candidates_impl(
380 // Also note that when we've got a receiver like &S, even if the method we 381 // Also note that when we've got a receiver like &S, even if the method we
381 // find in the end takes &self, we still do the autoderef step (just as 382 // find in the end takes &self, we still do the autoderef step (just as
382 // rustc does an autoderef and then autoref again). 383 // rustc does an autoderef and then autoref again).
383 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 384 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
384 385
385 // We have to be careful about the order we're looking at candidates 386 // We have to be careful about the order we're looking at candidates
386 // in here. Consider the case where we're resolving `x.clone()` 387 // in here. Consider the case where we're resolving `x.clone()`
@@ -452,7 +453,7 @@ fn iterate_method_candidates_with_autoref(
452 return true; 453 return true;
453 } 454 }
454 let refed = Canonical { 455 let refed = Canonical {
455 kinds: deref_chain[0].kinds.clone(), 456 binders: deref_chain[0].binders.clone(),
456 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 457 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
457 }; 458 };
458 if iterate_method_candidates_by_receiver( 459 if iterate_method_candidates_by_receiver(
@@ -469,7 +470,7 @@ fn iterate_method_candidates_with_autoref(
469 return true; 470 return true;
470 } 471 }
471 let ref_muted = Canonical { 472 let ref_muted = Canonical {
472 kinds: deref_chain[0].kinds.clone(), 473 binders: deref_chain[0].binders.clone(),
473 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 474 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
474 }; 475 };
475 if iterate_method_candidates_by_receiver( 476 if iterate_method_candidates_by_receiver(
@@ -646,7 +647,7 @@ pub fn resolve_indexing_op(
646 krate: CrateId, 647 krate: CrateId,
647 index_trait: TraitId, 648 index_trait: TraitId,
648) -> Option<Canonical<Ty>> { 649) -> Option<Canonical<Ty>> {
649 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 650 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
650 let deref_chain = autoderef_method_receiver(db, krate, ty); 651 let deref_chain = autoderef_method_receiver(db, krate, ty);
651 for ty in deref_chain { 652 for ty in deref_chain {
652 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 653 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
@@ -710,19 +711,28 @@ pub(crate) fn inherent_impl_substs(
710 // we create a var for each type parameter of the impl; we need to keep in 711 // we create a var for each type parameter of the impl; we need to keep in
711 // mind here that `self_ty` might have vars of its own 712 // mind here that `self_ty` might have vars of its own
712 let vars = Substitution::build_for_def(db, impl_id) 713 let vars = Substitution::build_for_def(db, impl_id)
713 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) 714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
714 .build(); 715 .build();
715 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
716 let mut kinds = self_ty.kinds.to_vec(); 717 let mut kinds = self_ty.binders.interned().to_vec();
717 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); 718 kinds.extend(
718 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 719 iter::repeat(chalk_ir::WithKind::new(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT,
722 ))
723 .take(vars.len()),
724 );
725 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
727 value: (self_ty_with_vars, self_ty.value.clone()),
728 };
719 let substs = super::infer::unify(&tys); 729 let substs = super::infer::unify(&tys);
720 // We only want the substs for the vars we added, not the ones from self_ty. 730 // We only want the substs for the vars we added, not the ones from self_ty.
721 // Also, if any of the vars we added are still in there, we replace them by 731 // Also, if any of the vars we added are still in there, we replace them by
722 // Unknown. I think this can only really happen if self_ty contained 732 // Unknown. I think this can only really happen if self_ty contained
723 // Unknown, and in that case we want the result to contain Unknown in those 733 // Unknown, and in that case we want the result to contain Unknown in those
724 // places again. 734 // places again.
725 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) 735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner)))
726} 736}
727 737
728/// 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
@@ -801,15 +811,24 @@ fn generic_implements_goal(
801 trait_: TraitId, 811 trait_: TraitId,
802 self_ty: Canonical<Ty>, 812 self_ty: Canonical<Ty>,
803) -> Canonical<InEnvironment<super::DomainGoal>> { 813) -> Canonical<InEnvironment<super::DomainGoal>> {
804 let mut kinds = self_ty.kinds.to_vec(); 814 let mut kinds = self_ty.binders.interned().to_vec();
805 let substs = super::Substitution::build_for_def(db, trait_) 815 let substs = super::Substitution::build_for_def(db, trait_)
806 .push(self_ty.value) 816 .push(self_ty.value)
807 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
808 .build(); 818 .build();
809 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 819 kinds.extend(
820 iter::repeat(chalk_ir::WithKind::new(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT,
823 ))
824 .take(substs.len() - 1),
825 );
810 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; 826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
811 let obligation = trait_ref.cast(&Interner); 827 let obligation = trait_ref.cast(&Interner);
812 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 828 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
830 value: InEnvironment::new(env.env.clone(), obligation),
831 }
813} 832}
814 833
815fn autoderef_method_receiver( 834fn autoderef_method_receiver(
@@ -822,9 +841,9 @@ fn autoderef_method_receiver(
822 if let Some(TyKind::Array(parameters)) = 841 if let Some(TyKind::Array(parameters)) =
823 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 842 deref_chain.last().map(|ty| ty.value.interned(&Interner))
824 { 843 {
825 let kinds = deref_chain.last().unwrap().kinds.clone(); 844 let kinds = deref_chain.last().unwrap().binders.clone();
826 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
827 deref_chain.push(Canonical { value: unsized_ty, kinds }) 846 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
828 } 847 }
829 deref_chain 848 deref_chain
830} 849}