diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index ad908f957..e4b1f92e4 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -132,6 +132,12 @@ impl TypeWalk for ProjectionTy { | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
136 | pub struct DynTy { | ||
137 | /// The unknown self type. | ||
138 | pub bounds: Binders<QuantifiedWhereClauses>, | ||
139 | } | ||
140 | |||
135 | pub type FnSig = chalk_ir::FnSig<Interner>; | 141 | pub type FnSig = chalk_ir::FnSig<Interner>; |
136 | 142 | ||
137 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 143 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -283,7 +289,7 @@ pub enum TyKind { | |||
283 | /// represents the `Self` type inside the bounds. This is currently | 289 | /// represents the `Self` type inside the bounds. This is currently |
284 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it | 290 | /// implicit; Chalk has the `Binders` struct to make it explicit, but it |
285 | /// didn't seem worth the overhead yet. | 291 | /// didn't seem worth the overhead yet. |
286 | Dyn(Arc<[WhereClause]>), | 292 | Dyn(DynTy), |
287 | 293 | ||
288 | /// A placeholder for a type which could not be computed; this is propagated | 294 | /// A placeholder for a type which could not be computed; this is propagated |
289 | /// to avoid useless error messages. Doubles as a placeholder where type | 295 | /// to avoid useless error messages. Doubles as a placeholder where type |
@@ -490,6 +496,13 @@ impl<T> Binders<T> { | |||
490 | Self { num_binders, value } | 496 | Self { num_binders, value } |
491 | } | 497 | } |
492 | 498 | ||
499 | pub fn wrap_empty(value: T) -> Self | ||
500 | where | ||
501 | T: TypeWalk, | ||
502 | { | ||
503 | Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } | ||
504 | } | ||
505 | |||
493 | pub fn as_ref(&self) -> Binders<&T> { | 506 | pub fn as_ref(&self) -> Binders<&T> { |
494 | Binders { num_binders: self.num_binders, value: &self.value } | 507 | Binders { num_binders: self.num_binders, value: &self.value } |
495 | } | 508 | } |
@@ -501,6 +514,10 @@ impl<T> Binders<T> { | |||
501 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | 514 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { |
502 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | 515 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) |
503 | } | 516 | } |
517 | |||
518 | pub fn skip_binders(&self) -> &T { | ||
519 | &self.value | ||
520 | } | ||
504 | } | 521 | } |
505 | 522 | ||
506 | impl<T: Clone> Binders<&T> { | 523 | impl<T: Clone> Binders<&T> { |
@@ -614,6 +631,24 @@ impl TypeWalk for WhereClause { | |||
614 | } | 631 | } |
615 | } | 632 | } |
616 | 633 | ||
634 | pub type QuantifiedWhereClause = Binders<WhereClause>; | ||
635 | |||
636 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
637 | pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>); | ||
638 | |||
639 | impl QuantifiedWhereClauses { | ||
640 | pub fn from_iter( | ||
641 | _interner: &Interner, | ||
642 | elements: impl IntoIterator<Item = QuantifiedWhereClause>, | ||
643 | ) -> Self { | ||
644 | QuantifiedWhereClauses(elements.into_iter().collect()) | ||
645 | } | ||
646 | |||
647 | pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> { | ||
648 | &self.0 | ||
649 | } | ||
650 | } | ||
651 | |||
617 | /// Basically a claim (currently not validated / checked) that the contained | 652 | /// Basically a claim (currently not validated / checked) that the contained |
618 | /// type / trait ref contains no inference variables; any inference variables it | 653 | /// type / trait ref contains no inference variables; any inference variables it |
619 | /// contained have been replaced by bound variables, and `kinds` tells us how | 654 | /// contained have been replaced by bound variables, and `kinds` tells us how |
@@ -810,12 +845,14 @@ impl Ty { | |||
810 | } | 845 | } |
811 | 846 | ||
812 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 847 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
813 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 848 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
814 | match self.interned(&Interner) { | 849 | match self.interned(&Interner) { |
815 | TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { | 850 | TyKind::Dyn(dyn_ty) => { |
816 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 851 | dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { |
817 | _ => None, | 852 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
818 | }), | 853 | _ => None, |
854 | }) | ||
855 | } | ||
819 | _ => None, | 856 | _ => None, |
820 | } | 857 | } |
821 | } | 858 | } |
@@ -892,7 +929,7 @@ impl Ty { | |||
892 | } | 929 | } |
893 | } | 930 | } |
894 | 931 | ||
895 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> { | 932 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> { |
896 | match self.interned(&Interner) { | 933 | match self.interned(&Interner) { |
897 | TyKind::OpaqueType(opaque_ty_id, ..) => { | 934 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
898 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { | 935 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
@@ -905,10 +942,13 @@ impl Ty { | |||
905 | // This is only used by type walking. | 942 | // This is only used by type walking. |
906 | // Parameters will be walked outside, and projection predicate is not used. | 943 | // Parameters will be walked outside, and projection predicate is not used. |
907 | // So just provide the Future trait. | 944 | // So just provide the Future trait. |
908 | let impl_bound = WhereClause::Implemented(TraitRef { | 945 | let impl_bound = Binders::new( |
909 | trait_id: to_chalk_trait_id(future_trait), | 946 | 0, |
910 | substitution: Substitution::empty(), | 947 | WhereClause::Implemented(TraitRef { |
911 | }); | 948 | trait_id: to_chalk_trait_id(future_trait), |
949 | substitution: Substitution::empty(), | ||
950 | }), | ||
951 | ); | ||
912 | Some(vec![impl_bound]) | 952 | Some(vec![impl_bound]) |
913 | } else { | 953 | } else { |
914 | None | 954 | None |
@@ -953,6 +993,7 @@ impl Ty { | |||
953 | }) => proj.self_type_parameter() == self, | 993 | }) => proj.self_type_parameter() == self, |
954 | _ => false, | 994 | _ => false, |
955 | }) | 995 | }) |
996 | .map(Binders::wrap_empty) | ||
956 | .collect_vec(); | 997 | .collect_vec(); |
957 | 998 | ||
958 | Some(predicates) | 999 | Some(predicates) |
@@ -1094,8 +1135,8 @@ impl TypeWalk for Ty { | |||
1094 | t.walk(f); | 1135 | t.walk(f); |
1095 | } | 1136 | } |
1096 | } | 1137 | } |
1097 | TyKind::Dyn(predicates) => { | 1138 | TyKind::Dyn(dyn_ty) => { |
1098 | for p in predicates.iter() { | 1139 | for p in dyn_ty.bounds.value.interned().iter() { |
1099 | p.walk(f); | 1140 | p.walk(f); |
1100 | } | 1141 | } |
1101 | } | 1142 | } |
@@ -1122,8 +1163,8 @@ impl TypeWalk for Ty { | |||
1122 | TyKind::Alias(AliasTy::Projection(p_ty)) => { | 1163 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1123 | p_ty.substitution.walk_mut_binders(f, binders); | 1164 | p_ty.substitution.walk_mut_binders(f, binders); |
1124 | } | 1165 | } |
1125 | TyKind::Dyn(predicates) => { | 1166 | TyKind::Dyn(dyn_ty) => { |
1126 | for p in make_mut_slice(predicates) { | 1167 | for p in make_mut_slice(&mut dyn_ty.bounds.value.0) { |
1127 | p.walk_mut_binders(f, binders.shifted_in()); | 1168 | p.walk_mut_binders(f, binders.shifted_in()); |
1128 | } | 1169 | } |
1129 | } | 1170 | } |
@@ -1173,7 +1214,7 @@ pub struct ReturnTypeImplTraits { | |||
1173 | 1214 | ||
1174 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1215 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
1175 | pub(crate) struct ReturnTypeImplTrait { | 1216 | pub(crate) struct ReturnTypeImplTrait { |
1176 | pub(crate) bounds: Binders<Vec<WhereClause>>, | 1217 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, |
1177 | } | 1218 | } |
1178 | 1219 | ||
1179 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | 1220 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { |