diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 62 |
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 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::Mutability; | 9 | use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; |
10 | use hir_def::{ | 10 | use 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 | ||
781 | fn autoderef_method_receiver( | 801 | fn 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 | } |