diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index bf7d5eded..a76586f0c 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -19,10 +19,9 @@ 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, | ||
23 | utils::all_super_traits, | 22 | utils::all_super_traits, |
24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, | 23 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, |
25 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, | 24 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, |
26 | TypeWalk, | 25 | TypeWalk, |
27 | }; | 26 | }; |
28 | 27 | ||
@@ -47,7 +46,7 @@ impl TyFingerprint { | |||
47 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 46 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not |
48 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 47 | /// `impl &S`. Hence, this will return `None` for reference types and such. |
49 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 48 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
50 | let fp = match *ty.interned(&Interner) { | 49 | let fp = match *ty.kind(&Interner) { |
51 | TyKind::Str => TyFingerprint::Str, | 50 | TyKind::Str => TyFingerprint::Str, |
52 | TyKind::Never => TyFingerprint::Never, | 51 | TyKind::Never => TyFingerprint::Never, |
53 | TyKind::Slice(..) => TyFingerprint::Slice, | 52 | TyKind::Slice(..) => TyFingerprint::Slice, |
@@ -243,7 +242,7 @@ impl Ty { | |||
243 | 242 | ||
244 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 243 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
245 | 244 | ||
246 | let lang_item_targets = match self.interned(&Interner) { | 245 | let lang_item_targets = match self.kind(&Interner) { |
247 | TyKind::Adt(AdtId(def_id), _) => { | 246 | TyKind::Adt(AdtId(def_id), _) => { |
248 | return mod_to_crate_ids(def_id.module(db.upcast())); | 247 | return mod_to_crate_ids(def_id.module(db.upcast())); |
249 | } | 248 | } |
@@ -563,7 +562,7 @@ fn iterate_trait_method_candidates( | |||
563 | // if ty is `dyn Trait`, the trait doesn't need to be in scope | 562 | // if ty is `dyn Trait`, the trait doesn't need to be in scope |
564 | let inherent_trait = | 563 | let inherent_trait = |
565 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); | 564 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); |
566 | let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { | 565 | let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) { |
567 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | 566 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope |
568 | env.traits_in_scope_from_clauses(&self_ty.value) | 567 | env.traits_in_scope_from_clauses(&self_ty.value) |
569 | .flat_map(|t| all_super_traits(db.upcast(), t)) | 568 | .flat_map(|t| all_super_traits(db.upcast(), t)) |
@@ -675,7 +674,7 @@ fn is_valid_candidate( | |||
675 | } | 674 | } |
676 | } | 675 | } |
677 | if let Some(receiver_ty) = receiver_ty { | 676 | if let Some(receiver_ty) = receiver_ty { |
678 | if !data.has_self_param { | 677 | if !data.has_self_param() { |
679 | return false; | 678 | return false; |
680 | } | 679 | } |
681 | let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { | 680 | let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { |
@@ -710,7 +709,7 @@ pub(crate) fn inherent_impl_substs( | |||
710 | ) -> Option<Substitution> { | 709 | ) -> Option<Substitution> { |
711 | // we create a var for each type parameter of the impl; we need to keep in | 710 | // we create a var for each type parameter of the impl; we need to keep in |
712 | // mind here that `self_ty` might have vars of its own | 711 | // mind here that `self_ty` might have vars of its own |
713 | let vars = Substitution::build_for_def(db, impl_id) | 712 | let vars = TyBuilder::subst_for_def(db, impl_id) |
714 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) | 713 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) |
715 | .build(); | 714 | .build(); |
716 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); | 715 | let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); |
@@ -720,7 +719,7 @@ pub(crate) fn inherent_impl_substs( | |||
720 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), | 719 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), |
721 | UniverseIndex::ROOT, | 720 | UniverseIndex::ROOT, |
722 | )) | 721 | )) |
723 | .take(vars.len()), | 722 | .take(vars.len(&Interner)), |
724 | ); | 723 | ); |
725 | let tys = Canonical { | 724 | let tys = Canonical { |
726 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 725 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
@@ -732,7 +731,8 @@ pub(crate) fn inherent_impl_substs( | |||
732 | // Unknown. I think this can only really happen if self_ty contained | 731 | // Unknown. I think this can only really happen if self_ty contained |
733 | // Unknown, and in that case we want the result to contain Unknown in those | 732 | // Unknown, and in that case we want the result to contain Unknown in those |
734 | // places again. | 733 | // places again. |
735 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) | 734 | substs |
735 | .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner))) | ||
736 | } | 736 | } |
737 | 737 | ||
738 | /// 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 |
@@ -740,7 +740,7 @@ pub(crate) fn inherent_impl_substs( | |||
740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { | 740 | fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { |
741 | s.fold_binders( | 741 | s.fold_binders( |
742 | &mut |ty, binders| { | 742 | &mut |ty, binders| { |
743 | if let TyKind::BoundVar(bound) = ty.interned(&Interner) { | 743 | if let TyKind::BoundVar(bound) = ty.kind(&Interner) { |
744 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 744 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { |
745 | TyKind::Unknown.intern(&Interner) | 745 | TyKind::Unknown.intern(&Interner) |
746 | } else { | 746 | } else { |
@@ -760,13 +760,13 @@ fn transform_receiver_ty( | |||
760 | self_ty: &Canonical<Ty>, | 760 | self_ty: &Canonical<Ty>, |
761 | ) -> Option<Ty> { | 761 | ) -> Option<Ty> { |
762 | let substs = match function_id.lookup(db.upcast()).container { | 762 | let substs = match function_id.lookup(db.upcast()).container { |
763 | AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) | 763 | AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id) |
764 | .push(self_ty.value.clone()) | 764 | .push(self_ty.value.clone()) |
765 | .fill_with_unknown() | 765 | .fill_with_unknown() |
766 | .build(), | 766 | .build(), |
767 | AssocContainerId::ImplId(impl_id) => { | 767 | AssocContainerId::ImplId(impl_id) => { |
768 | let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; | 768 | let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; |
769 | Substitution::build_for_def(db, function_id) | 769 | TyBuilder::subst_for_def(db, function_id) |
770 | .use_parent_substs(&impl_substs) | 770 | .use_parent_substs(&impl_substs) |
771 | .fill_with_unknown() | 771 | .fill_with_unknown() |
772 | .build() | 772 | .build() |
@@ -812,7 +812,7 @@ fn generic_implements_goal( | |||
812 | self_ty: Canonical<Ty>, | 812 | self_ty: Canonical<Ty>, |
813 | ) -> Canonical<InEnvironment<super::DomainGoal>> { | 813 | ) -> Canonical<InEnvironment<super::DomainGoal>> { |
814 | let mut kinds = self_ty.binders.interned().to_vec(); | 814 | let mut kinds = self_ty.binders.interned().to_vec(); |
815 | let substs = super::Substitution::build_for_def(db, trait_) | 815 | let trait_ref = TyBuilder::trait_ref(db, trait_) |
816 | .push(self_ty.value) | 816 | .push(self_ty.value) |
817 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) | 817 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) |
818 | .build(); | 818 | .build(); |
@@ -821,9 +821,8 @@ fn generic_implements_goal( | |||
821 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), | 821 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), |
822 | UniverseIndex::ROOT, | 822 | UniverseIndex::ROOT, |
823 | )) | 823 | )) |
824 | .take(substs.len() - 1), | 824 | .take(trait_ref.substitution.len(&Interner) - 1), |
825 | ); | 825 | ); |
826 | let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; | ||
827 | let obligation = trait_ref.cast(&Interner); | 826 | let obligation = trait_ref.cast(&Interner); |
828 | Canonical { | 827 | Canonical { |
829 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), | 828 | binders: CanonicalVarKinds::from_iter(&Interner, kinds), |
@@ -838,9 +837,7 @@ fn autoderef_method_receiver( | |||
838 | ) -> Vec<Canonical<Ty>> { | 837 | ) -> Vec<Canonical<Ty>> { |
839 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 838 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
840 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 839 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
841 | if let Some(TyKind::Array(parameters)) = | 840 | if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) { |
842 | deref_chain.last().map(|ty| ty.value.interned(&Interner)) | ||
843 | { | ||
844 | let kinds = deref_chain.last().unwrap().binders.clone(); | 841 | let kinds = deref_chain.last().unwrap().binders.clone(); |
845 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); | 842 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
846 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) | 843 | deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) |