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.rs47
1 files changed, 35 insertions, 12 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 48bbcfd9f..08e385a42 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -577,6 +577,7 @@ fn iterate_method_candidates_by_receiver(
577 if iterate_inherent_methods( 577 if iterate_inherent_methods(
578 self_ty, 578 self_ty,
579 db, 579 db,
580 env.clone(),
580 name, 581 name,
581 Some(receiver_ty), 582 Some(receiver_ty),
582 krate, 583 krate,
@@ -613,8 +614,16 @@ fn iterate_method_candidates_for_self_ty(
613 name: Option<&Name>, 614 name: Option<&Name>,
614 mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 615 mut callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
615) -> bool { 616) -> bool {
616 if iterate_inherent_methods(self_ty, db, name, None, krate, visible_from_module, &mut callback) 617 if iterate_inherent_methods(
617 { 618 self_ty,
619 db,
620 env.clone(),
621 name,
622 None,
623 krate,
624 visible_from_module,
625 &mut callback,
626 ) {
618 return true; 627 return true;
619 } 628 }
620 iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback) 629 iterate_trait_method_candidates(self_ty, db, env, krate, traits_in_scope, name, None, callback)
@@ -653,12 +662,12 @@ fn iterate_trait_method_candidates(
653 for (_name, item) in data.items.iter() { 662 for (_name, item) in data.items.iter() {
654 // Don't pass a `visible_from_module` down to `is_valid_candidate`, 663 // Don't pass a `visible_from_module` down to `is_valid_candidate`,
655 // since only inherent methods should be included into visibility checking. 664 // since only inherent methods should be included into visibility checking.
656 if !is_valid_candidate(db, name, receiver_ty, *item, self_ty, None) { 665 if !is_valid_candidate(db, env.clone(), name, receiver_ty, *item, self_ty, None) {
657 continue; 666 continue;
658 } 667 }
659 if !known_implemented { 668 if !known_implemented {
660 let goal = generic_implements_goal(db, env.clone(), t, self_ty.clone()); 669 let goal = generic_implements_goal(db, env.clone(), t, self_ty.clone());
661 if db.trait_solve(krate, goal).is_none() { 670 if db.trait_solve(krate, goal.cast(&Interner)).is_none() {
662 continue 'traits; 671 continue 'traits;
663 } 672 }
664 } 673 }
@@ -675,6 +684,7 @@ fn iterate_trait_method_candidates(
675fn iterate_inherent_methods( 684fn iterate_inherent_methods(
676 self_ty: &Canonical<Ty>, 685 self_ty: &Canonical<Ty>,
677 db: &dyn HirDatabase, 686 db: &dyn HirDatabase,
687 env: Arc<TraitEnvironment>,
678 name: Option<&Name>, 688 name: Option<&Name>,
679 receiver_ty: Option<&Canonical<Ty>>, 689 receiver_ty: Option<&Canonical<Ty>>,
680 krate: CrateId, 690 krate: CrateId,
@@ -690,14 +700,24 @@ fn iterate_inherent_methods(
690 700
691 for &impl_def in impls.for_self_ty(&self_ty.value) { 701 for &impl_def in impls.for_self_ty(&self_ty.value) {
692 for &item in db.impl_data(impl_def).items.iter() { 702 for &item in db.impl_data(impl_def).items.iter() {
693 if !is_valid_candidate(db, name, receiver_ty, item, self_ty, visible_from_module) { 703 if !is_valid_candidate(
704 db,
705 env.clone(),
706 name,
707 receiver_ty,
708 item,
709 self_ty,
710 visible_from_module,
711 ) {
694 continue; 712 continue;
695 } 713 }
696 // we have to check whether the self type unifies with the type 714 // we have to check whether the self type unifies with the type
697 // that the impl is for. If we have a receiver type, this 715 // that the impl is for. If we have a receiver type, this
698 // already happens in `is_valid_candidate` above; if not, we 716 // already happens in `is_valid_candidate` above; if not, we
699 // check it here 717 // check it here
700 if receiver_ty.is_none() && inherent_impl_substs(db, impl_def, self_ty).is_none() { 718 if receiver_ty.is_none()
719 && inherent_impl_substs(db, env.clone(), impl_def, self_ty).is_none()
720 {
701 cov_mark::hit!(impl_self_type_match_without_receiver); 721 cov_mark::hit!(impl_self_type_match_without_receiver);
702 continue; 722 continue;
703 } 723 }
@@ -722,7 +742,7 @@ pub fn resolve_indexing_op(
722 let deref_chain = autoderef_method_receiver(db, krate, ty); 742 let deref_chain = autoderef_method_receiver(db, krate, ty);
723 for ty in deref_chain { 743 for ty in deref_chain {
724 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone()); 744 let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
725 if db.trait_solve(krate, goal).is_some() { 745 if db.trait_solve(krate, goal.cast(&Interner)).is_some() {
726 return Some(ty); 746 return Some(ty);
727 } 747 }
728 } 748 }
@@ -731,6 +751,7 @@ pub fn resolve_indexing_op(
731 751
732fn is_valid_candidate( 752fn is_valid_candidate(
733 db: &dyn HirDatabase, 753 db: &dyn HirDatabase,
754 env: Arc<TraitEnvironment>,
734 name: Option<&Name>, 755 name: Option<&Name>,
735 receiver_ty: Option<&Canonical<Ty>>, 756 receiver_ty: Option<&Canonical<Ty>>,
736 item: AssocItemId, 757 item: AssocItemId,
@@ -749,7 +770,7 @@ fn is_valid_candidate(
749 if !data.has_self_param() { 770 if !data.has_self_param() {
750 return false; 771 return false;
751 } 772 }
752 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 773 let transformed_receiver_ty = match transform_receiver_ty(db, env, m, self_ty) {
753 Some(ty) => ty, 774 Some(ty) => ty,
754 None => return false, 775 None => return false,
755 }; 776 };
@@ -776,6 +797,7 @@ fn is_valid_candidate(
776 797
777pub(crate) fn inherent_impl_substs( 798pub(crate) fn inherent_impl_substs(
778 db: &dyn HirDatabase, 799 db: &dyn HirDatabase,
800 env: Arc<TraitEnvironment>,
779 impl_id: ImplId, 801 impl_id: ImplId,
780 self_ty: &Canonical<Ty>, 802 self_ty: &Canonical<Ty>,
781) -> Option<Substitution> { 803) -> Option<Substitution> {
@@ -798,7 +820,7 @@ pub(crate) fn inherent_impl_substs(
798 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 820 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
799 value: (self_ty_with_vars, self_ty.value.clone()), 821 value: (self_ty_with_vars, self_ty.value.clone()),
800 }; 822 };
801 let substs = super::infer::unify(&tys)?; 823 let substs = super::infer::unify(db, env, &tys)?;
802 // We only want the substs for the vars we added, not the ones from self_ty. 824 // We only want the substs for the vars we added, not the ones from self_ty.
803 // Also, if any of the vars we added are still in there, we replace them by 825 // Also, if any of the vars we added are still in there, we replace them by
804 // Unknown. I think this can only really happen if self_ty contained 826 // Unknown. I think this can only really happen if self_ty contained
@@ -823,6 +845,7 @@ fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution
823 845
824fn transform_receiver_ty( 846fn transform_receiver_ty(
825 db: &dyn HirDatabase, 847 db: &dyn HirDatabase,
848 env: Arc<TraitEnvironment>,
826 function_id: FunctionId, 849 function_id: FunctionId,
827 self_ty: &Canonical<Ty>, 850 self_ty: &Canonical<Ty>,
828) -> Option<Ty> { 851) -> Option<Ty> {
@@ -832,7 +855,7 @@ fn transform_receiver_ty(
832 .fill_with_unknown() 855 .fill_with_unknown()
833 .build(), 856 .build(),
834 AssocContainerId::ImplId(impl_id) => { 857 AssocContainerId::ImplId(impl_id) => {
835 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 858 let impl_substs = inherent_impl_substs(db, env, impl_id, &self_ty)?;
836 TyBuilder::subst_for_def(db, function_id) 859 TyBuilder::subst_for_def(db, function_id)
837 .use_parent_substs(&impl_substs) 860 .use_parent_substs(&impl_substs)
838 .fill_with_unknown() 861 .fill_with_unknown()
@@ -852,7 +875,7 @@ pub fn implements_trait(
852 trait_: TraitId, 875 trait_: TraitId,
853) -> bool { 876) -> bool {
854 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 877 let goal = generic_implements_goal(db, env, trait_, ty.clone());
855 let solution = db.trait_solve(krate, goal); 878 let solution = db.trait_solve(krate, goal.cast(&Interner));
856 879
857 solution.is_some() 880 solution.is_some()
858} 881}
@@ -865,7 +888,7 @@ pub fn implements_trait_unique(
865 trait_: TraitId, 888 trait_: TraitId,
866) -> bool { 889) -> bool {
867 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 890 let goal = generic_implements_goal(db, env, trait_, ty.clone());
868 let solution = db.trait_solve(krate, goal); 891 let solution = db.trait_solve(krate, goal.cast(&Interner));
869 892
870 matches!(solution, Some(crate::Solution::Unique(_))) 893 matches!(solution, Some(crate::Solution::Unique(_)))
871} 894}