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.rs62
1 files changed, 41 insertions, 21 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 943d3339b..8e986ddde 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::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,
@@ -19,9 +19,11 @@ 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,
22 utils::all_super_traits, 23 utils::all_super_traits,
23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
24 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind,
26 TypeWalk,
25}; 27};
26 28
27/// This is used as a key for indexing impls. 29/// This is used as a key for indexing impls.
@@ -101,7 +103,7 @@ impl TraitImpls {
101 for (_module_id, module_data) in crate_def_map.modules() { 103 for (_module_id, module_data) in crate_def_map.modules() {
102 for impl_id in module_data.scope.impls() { 104 for impl_id in module_data.scope.impls() {
103 let target_trait = match db.impl_trait(impl_id) { 105 let target_trait = match db.impl_trait(impl_id) {
104 Some(tr) => tr.value.trait_, 106 Some(tr) => tr.value.hir_trait_id(),
105 None => continue, 107 None => continue,
106 }; 108 };
107 let self_ty = db.impl_self_ty(impl_id); 109 let self_ty = db.impl_self_ty(impl_id);
@@ -374,7 +376,7 @@ fn iterate_method_candidates_impl(
374 // Also note that when we've got a receiver like &S, even if the method we 376 // Also note that when we've got a receiver like &S, even if the method we
375 // find in the end takes &self, we still do the autoderef step (just as 377 // find in the end takes &self, we still do the autoderef step (just as
376 // rustc does an autoderef and then autoref again). 378 // rustc does an autoderef and then autoref again).
377 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 379 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
378 380
379 // We have to be careful about the order we're looking at candidates 381 // We have to be careful about the order we're looking at candidates
380 // in here. Consider the case where we're resolving `x.clone()` 382 // in here. Consider the case where we're resolving `x.clone()`
@@ -442,7 +444,7 @@ fn iterate_method_candidates_with_autoref(
442 return true; 444 return true;
443 } 445 }
444 let refed = Canonical { 446 let refed = Canonical {
445 kinds: deref_chain[0].kinds.clone(), 447 binders: deref_chain[0].binders.clone(),
446 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 448 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
447 }; 449 };
448 if iterate_method_candidates_by_receiver( 450 if iterate_method_candidates_by_receiver(
@@ -458,7 +460,7 @@ fn iterate_method_candidates_with_autoref(
458 return true; 460 return true;
459 } 461 }
460 let ref_muted = Canonical { 462 let ref_muted = Canonical {
461 kinds: deref_chain[0].kinds.clone(), 463 binders: deref_chain[0].binders.clone(),
462 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 464 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
463 }; 465 };
464 if iterate_method_candidates_by_receiver( 466 if iterate_method_candidates_by_receiver(
@@ -620,7 +622,7 @@ pub fn resolve_indexing_op(
620 krate: CrateId, 622 krate: CrateId,
621 index_trait: TraitId, 623 index_trait: TraitId,
622) -> Option<Canonical<Ty>> { 624) -> Option<Canonical<Ty>> {
623 let ty = InEnvironment { value: ty.clone(), environment: env.clone() }; 625 let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
624 let deref_chain = autoderef_method_receiver(db, krate, ty); 626 let deref_chain = autoderef_method_receiver(db, krate, ty);
625 for ty in deref_chain { 627 for ty in deref_chain {
626 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 628 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
@@ -676,19 +678,28 @@ pub(crate) fn inherent_impl_substs(
676 // we create a var for each type parameter of the impl; we need to keep in 678 // we create a var for each type parameter of the impl; we need to keep in
677 // mind here that `self_ty` might have vars of its own 679 // mind here that `self_ty` might have vars of its own
678 let vars = Substitution::build_for_def(db, impl_id) 680 let vars = Substitution::build_for_def(db, impl_id)
679 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.kinds.len()) 681 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
680 .build(); 682 .build();
681 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 683 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
682 let mut kinds = self_ty.kinds.to_vec(); 684 let mut kinds = self_ty.binders.interned().to_vec();
683 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len())); 685 kinds.extend(
684 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 686 iter::repeat(chalk_ir::WithKind::new(
687 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
688 UniverseIndex::ROOT,
689 ))
690 .take(vars.len()),
691 );
692 let tys = Canonical {
693 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
694 value: (self_ty_with_vars, self_ty.value.clone()),
695 };
685 let substs = super::infer::unify(&tys); 696 let substs = super::infer::unify(&tys);
686 // We only want the substs for the vars we added, not the ones from self_ty. 697 // We only want the substs for the vars we added, not the ones from self_ty.
687 // Also, if any of the vars we added are still in there, we replace them by 698 // Also, if any of the vars we added are still in there, we replace them by
688 // Unknown. I think this can only really happen if self_ty contained 699 // Unknown. I think this can only really happen if self_ty contained
689 // Unknown, and in that case we want the result to contain Unknown in those 700 // Unknown, and in that case we want the result to contain Unknown in those
690 // places again. 701 // places again.
691 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.kinds.len())) 702 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner)))
692} 703}
693 704
694/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 705/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -766,16 +777,25 @@ fn generic_implements_goal(
766 env: Arc<TraitEnvironment>, 777 env: Arc<TraitEnvironment>,
767 trait_: TraitId, 778 trait_: TraitId,
768 self_ty: Canonical<Ty>, 779 self_ty: Canonical<Ty>,
769) -> Canonical<InEnvironment<super::Obligation>> { 780) -> Canonical<InEnvironment<super::DomainGoal>> {
770 let mut kinds = self_ty.kinds.to_vec(); 781 let mut kinds = self_ty.binders.interned().to_vec();
771 let substs = super::Substitution::build_for_def(db, trait_) 782 let substs = super::Substitution::build_for_def(db, trait_)
772 .push(self_ty.value) 783 .push(self_ty.value)
773 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 784 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
774 .build(); 785 .build();
775 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 786 kinds.extend(
776 let trait_ref = TraitRef { trait_, substs }; 787 iter::repeat(chalk_ir::WithKind::new(
777 let obligation = super::Obligation::Trait(trait_ref); 788 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
778 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 789 UniverseIndex::ROOT,
790 ))
791 .take(substs.len() - 1),
792 );
793 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
794 let obligation = trait_ref.cast(&Interner);
795 Canonical {
796 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
797 value: InEnvironment::new(env.env.clone(), obligation),
798 }
779} 799}
780 800
781fn autoderef_method_receiver( 801fn autoderef_method_receiver(
@@ -788,9 +808,9 @@ fn autoderef_method_receiver(
788 if let Some(TyKind::Array(parameters)) = 808 if let Some(TyKind::Array(parameters)) =
789 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 809 deref_chain.last().map(|ty| ty.value.interned(&Interner))
790 { 810 {
791 let kinds = deref_chain.last().unwrap().kinds.clone(); 811 let kinds = deref_chain.last().unwrap().binders.clone();
792 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 812 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
793 deref_chain.push(Canonical { value: unsized_ty, kinds }) 813 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
794 } 814 }
795 deref_chain 815 deref_chain
796} 816}