diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 105 |
1 files changed, 85 insertions, 20 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index c46529879..0f49dd39b 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -61,6 +61,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>; | |||
61 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 61 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
62 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | 62 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; |
63 | 63 | ||
64 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | ||
65 | |||
64 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | 66 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; |
65 | 67 | ||
66 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 68 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -106,6 +108,10 @@ impl ProjectionTy { | |||
106 | } | 108 | } |
107 | } | 109 | } |
108 | 110 | ||
111 | pub fn self_type_parameter(&self) -> &Ty { | ||
112 | &self.substitution[0] | ||
113 | } | ||
114 | |||
109 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { | 115 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { |
110 | match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { | 116 | match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { |
111 | AssocContainerId::TraitId(it) => it, | 117 | AssocContainerId::TraitId(it) => it, |
@@ -128,6 +134,12 @@ impl TypeWalk for ProjectionTy { | |||
128 | } | 134 | } |
129 | } | 135 | } |
130 | 136 | ||
137 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
138 | pub struct DynTy { | ||
139 | /// The unknown self type. | ||
140 | pub bounds: Binders<QuantifiedWhereClauses>, | ||
141 | } | ||
142 | |||
131 | pub type FnSig = chalk_ir::FnSig<Interner>; | 143 | pub type FnSig = chalk_ir::FnSig<Interner>; |
132 | 144 | ||
133 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 145 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -279,7 +291,7 @@ pub enum TyKind { | |||
279 | /// represents the `Self` type inside the bounds. This is currently | 291 | /// represents the `Self` type inside the bounds. This is currently |
280 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it | 292 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it |
281 | /// didn't seem worth the overhead yet. | 293 | /// didn't seem worth the overhead yet. |
282 | Dyn(Arc<[WhereClause]>), | 294 | Dyn(DynTy), |
283 | 295 | ||
284 | /// A placeholder for a type which could not be computed; this is propagated | 296 | /// A placeholder for a type which could not be computed; this is propagated |
285 | /// to avoid useless error messages. Doubles as a placeholder where type | 297 | /// to avoid useless error messages. Doubles as a placeholder where type |
@@ -486,6 +498,13 @@ impl<T> Binders<T> { | |||
486 | Self { num_binders, value } | 498 | Self { num_binders, value } |
487 | } | 499 | } |
488 | 500 | ||
501 | pub fn wrap_empty(value: T) -> Self | ||
502 | where | ||
503 | T: TypeWalk, | ||
504 | { | ||
505 | Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } | ||
506 | } | ||
507 | |||
489 | pub fn as_ref(&self) -> Binders<&T> { | 508 | pub fn as_ref(&self) -> Binders<&T> { |
490 | Binders { num_binders: self.num_binders, value: &self.value } | 509 | Binders { num_binders: self.num_binders, value: &self.value } |
491 | } | 510 | } |
@@ -497,6 +516,14 @@ impl<T> Binders<T> { | |||
497 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | 516 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { |
498 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | 517 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) |
499 | } | 518 | } |
519 | |||
520 | pub fn skip_binders(&self) -> &T { | ||
521 | &self.value | ||
522 | } | ||
523 | |||
524 | pub fn into_value_and_skipped_binders(self) -> (T, usize) { | ||
525 | (self.value, self.num_binders) | ||
526 | } | ||
500 | } | 527 | } |
501 | 528 | ||
502 | impl<T: Clone> Binders<&T> { | 529 | impl<T: Clone> Binders<&T> { |
@@ -610,6 +637,24 @@ impl TypeWalk for WhereClause { | |||
610 | } | 637 | } |
611 | } | 638 | } |
612 | 639 | ||
640 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
641 | |||
642 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
643 | pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>); | ||
644 | |||
645 | impl QuantifiedWhereClauses { | ||
646 | pub fn from_iter( | ||
647 | _interner: &Interner, | ||
648 | elements: impl IntoIterator<Item = QuantifiedWhereClause>, | ||
649 | ) -> Self { | ||
650 | QuantifiedWhereClauses(elements.into_iter().collect()) | ||
651 | } | ||
652 | |||
653 | pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> { | ||
654 | &self.0 | ||
655 | } | ||
656 | } | ||
657 | |||
613 | /// Basically a claim (currently not validated / checked) that the contained | 658 | /// Basically a claim (currently not validated / checked) that the contained |
614 | /// type / trait ref contains no inference variables; any inference variables it | 659 | /// type / trait ref contains no inference variables; any inference variables it |
615 | /// contained have been replaced by bound variables, and `kinds` tells us how | 660 | /// contained have been replaced by bound variables, and `kinds` tells us how |
@@ -619,12 +664,18 @@ impl TypeWalk for WhereClause { | |||
619 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 664 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
620 | pub struct Canonical<T> { | 665 | pub struct Canonical<T> { |
621 | pub value: T, | 666 | pub value: T, |
622 | pub kinds: Arc<[TyVariableKind]>, | 667 | pub binders: CanonicalVarKinds, |
623 | } | 668 | } |
624 | 669 | ||
625 | impl<T> Canonical<T> { | 670 | impl<T> Canonical<T> { |
626 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { | 671 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { |
627 | Self { value, kinds: kinds.into_iter().collect() } | 672 | let kinds = kinds.into_iter().map(|tk| { |
673 | chalk_ir::CanonicalVarKind::new( | ||
674 | chalk_ir::VariableKind::Ty(tk), | ||
675 | chalk_ir::UniverseIndex::ROOT, | ||
676 | ) | ||
677 | }); | ||
678 | Self { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) } | ||
628 | } | 679 | } |
629 | } | 680 | } |
630 | 681 | ||
@@ -806,12 +857,14 @@ impl Ty { | |||
806 | } | 857 | } |
807 | 858 | ||
808 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 859 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
809 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 860 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
810 | match self.interned(&Interner) { | 861 | match self.interned(&Interner) { |
811 | TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { | 862 | TyKind::Dyn(dyn_ty) => { |
812 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 863 | dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { |
813 | _ => None, | 864 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
814 | }), | 865 | _ => None, |
866 | }) | ||
867 | } | ||
815 | _ => None, | 868 | _ => None, |
816 | } | 869 | } |
817 | } | 870 | } |
@@ -888,7 +941,7 @@ impl Ty { | |||
888 | } | 941 | } |
889 | } | 942 | } |
890 | 943 | ||
891 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> { | 944 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> { |
892 | match self.interned(&Interner) { | 945 | match self.interned(&Interner) { |
893 | TyKind::OpaqueType(opaque_ty_id, ..) => { | 946 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
894 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { | 947 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
@@ -901,10 +954,13 @@ impl Ty { | |||
901 | // This is only used by type walking. | 954 | // This is only used by type walking. |
902 | // Parameters will be walked outside, and projection predicate is not used. | 955 | // Parameters will be walked outside, and projection predicate is not used. |
903 | // So just provide the Future trait. | 956 | // So just provide the Future trait. |
904 | let impl_bound = WhereClause::Implemented(TraitRef { | 957 | let impl_bound = Binders::new( |
905 | trait_id: to_chalk_trait_id(future_trait), | 958 | 0, |
906 | substitution: Substitution::empty(), | 959 | WhereClause::Implemented(TraitRef { |
907 | }); | 960 | trait_id: to_chalk_trait_id(future_trait), |
961 | substitution: Substitution::empty(), | ||
962 | }), | ||
963 | ); | ||
908 | Some(vec![impl_bound]) | 964 | Some(vec![impl_bound]) |
909 | } else { | 965 | } else { |
910 | None | 966 | None |
@@ -936,10 +992,19 @@ impl Ty { | |||
936 | let param_data = &generic_params.types[id.local_id]; | 992 | let param_data = &generic_params.types[id.local_id]; |
937 | match param_data.provenance { | 993 | match param_data.provenance { |
938 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | 994 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { |
995 | let substs = Substitution::type_params(db, id.parent); | ||
939 | let predicates = db | 996 | let predicates = db |
940 | .generic_predicates_for_param(id) | 997 | .generic_predicates(id.parent) |
941 | .into_iter() | 998 | .into_iter() |
942 | .map(|pred| pred.value.clone()) | 999 | .map(|pred| pred.clone().subst(&substs)) |
1000 | .filter(|wc| match &wc.skip_binders() { | ||
1001 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, | ||
1002 | WhereClause::AliasEq(AliasEq { | ||
1003 | alias: AliasTy::Projection(proj), | ||
1004 | ty: _, | ||
1005 | }) => proj.self_type_parameter() == self, | ||
1006 | _ => false, | ||
1007 | }) | ||
943 | .collect_vec(); | 1008 | .collect_vec(); |
944 | 1009 | ||
945 | Some(predicates) | 1010 | Some(predicates) |
@@ -1081,8 +1146,8 @@ impl TypeWalk for Ty { | |||
1081 | t.walk(f); | 1146 | t.walk(f); |
1082 | } | 1147 | } |
1083 | } | 1148 | } |
1084 | TyKind::Dyn(predicates) => { | 1149 | TyKind::Dyn(dyn_ty) => { |
1085 | for p in predicates.iter() { | 1150 | for p in dyn_ty.bounds.value.interned().iter() { |
1086 | p.walk(f); | 1151 | p.walk(f); |
1087 | } | 1152 | } |
1088 | } | 1153 | } |
@@ -1109,8 +1174,8 @@ impl TypeWalk for Ty { | |||
1109 | TyKind::Alias(AliasTy::Projection(p_ty)) => { | 1174 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1110 | p_ty.substitution.walk_mut_binders(f, binders); | 1175 | p_ty.substitution.walk_mut_binders(f, binders); |
1111 | } | 1176 | } |
1112 | TyKind::Dyn(predicates) => { | 1177 | TyKind::Dyn(dyn_ty) => { |
1113 | for p in make_mut_slice(predicates) { | 1178 | for p in make_mut_slice(&mut dyn_ty.bounds.value.0) { |
1114 | p.walk_mut_binders(f, binders.shifted_in()); | 1179 | p.walk_mut_binders(f, binders.shifted_in()); |
1115 | } | 1180 | } |
1116 | } | 1181 | } |
@@ -1160,7 +1225,7 @@ pub struct ReturnTypeImplTraits { | |||
1160 | 1225 | ||
1161 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1226 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
1162 | pub(crate) struct ReturnTypeImplTrait { | 1227 | pub(crate) struct ReturnTypeImplTrait { |
1163 | pub(crate) bounds: Binders<Vec<WhereClause>>, | 1228 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, |
1164 | } | 1229 | } |
1165 | 1230 | ||
1166 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | 1231 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { |