diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 53 |
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 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::{cast::Cast, 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, |
@@ -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 | ||
815 | fn autoderef_method_receiver( | 834 | fn 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 | } |