diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 90 |
1 files changed, 71 insertions, 19 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index ad908f957..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)] |
@@ -132,6 +134,12 @@ impl TypeWalk for ProjectionTy { | |||
132 | } | 134 | } |
133 | } | 135 | } |
134 | 136 | ||
137 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
138 | pub struct DynTy { | ||
139 | /// The unknown self type. | ||
140 | pub bounds: Binders<QuantifiedWhereClauses>, | ||
141 | } | ||
142 | |||
135 | pub type FnSig = chalk_ir::FnSig<Interner>; | 143 | pub type FnSig = chalk_ir::FnSig<Interner>; |
136 | 144 | ||
137 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 145 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -283,7 +291,7 @@ pub enum TyKind { | |||
283 | /// represents the `Self` type inside the bounds. This is currently | 291 | /// represents the `Self` type inside the bounds. This is currently |
284 | /// 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 |
285 | /// didn't seem worth the overhead yet. | 293 | /// didn't seem worth the overhead yet. |
286 | Dyn(Arc<[WhereClause]>), | 294 | Dyn(DynTy), |
287 | 295 | ||
288 | /// 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 |
289 | /// to avoid useless error messages. Doubles as a placeholder where type | 297 | /// to avoid useless error messages. Doubles as a placeholder where type |
@@ -490,6 +498,13 @@ impl<T> Binders<T> { | |||
490 | Self { num_binders, value } | 498 | Self { num_binders, value } |
491 | } | 499 | } |
492 | 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 | |||
493 | pub fn as_ref(&self) -> Binders<&T> { | 508 | pub fn as_ref(&self) -> Binders<&T> { |
494 | Binders { num_binders: self.num_binders, value: &self.value } | 509 | Binders { num_binders: self.num_binders, value: &self.value } |
495 | } | 510 | } |
@@ -501,6 +516,14 @@ impl<T> Binders<T> { | |||
501 | 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>> { |
502 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | 517 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) |
503 | } | 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 | } | ||
504 | } | 527 | } |
505 | 528 | ||
506 | impl<T: Clone> Binders<&T> { | 529 | impl<T: Clone> Binders<&T> { |
@@ -614,6 +637,24 @@ impl TypeWalk for WhereClause { | |||
614 | } | 637 | } |
615 | } | 638 | } |
616 | 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 | |||
617 | /// Basically a claim (currently not validated / checked) that the contained | 658 | /// Basically a claim (currently not validated / checked) that the contained |
618 | /// type / trait ref contains no inference variables; any inference variables it | 659 | /// type / trait ref contains no inference variables; any inference variables it |
619 | /// 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 |
@@ -623,12 +664,18 @@ impl TypeWalk for WhereClause { | |||
623 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 664 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
624 | pub struct Canonical<T> { | 665 | pub struct Canonical<T> { |
625 | pub value: T, | 666 | pub value: T, |
626 | pub kinds: Arc<[TyVariableKind]>, | 667 | pub binders: CanonicalVarKinds, |
627 | } | 668 | } |
628 | 669 | ||
629 | impl<T> Canonical<T> { | 670 | impl<T> Canonical<T> { |
630 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { | 671 | pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self { |
631 | 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) } | ||
632 | } | 679 | } |
633 | } | 680 | } |
634 | 681 | ||
@@ -810,12 +857,14 @@ impl Ty { | |||
810 | } | 857 | } |
811 | 858 | ||
812 | /// 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. |
813 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 860 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
814 | match self.interned(&Interner) { | 861 | match self.interned(&Interner) { |
815 | TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { | 862 | TyKind::Dyn(dyn_ty) => { |
816 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 863 | dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { |
817 | _ => None, | 864 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
818 | }), | 865 | _ => None, |
866 | }) | ||
867 | } | ||
819 | _ => None, | 868 | _ => None, |
820 | } | 869 | } |
821 | } | 870 | } |
@@ -892,7 +941,7 @@ impl Ty { | |||
892 | } | 941 | } |
893 | } | 942 | } |
894 | 943 | ||
895 | 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>> { |
896 | match self.interned(&Interner) { | 945 | match self.interned(&Interner) { |
897 | TyKind::OpaqueType(opaque_ty_id, ..) => { | 946 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
898 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { | 947 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
@@ -905,10 +954,13 @@ impl Ty { | |||
905 | // This is only used by type walking. | 954 | // This is only used by type walking. |
906 | // Parameters will be walked outside, and projection predicate is not used. | 955 | // Parameters will be walked outside, and projection predicate is not used. |
907 | // So just provide the Future trait. | 956 | // So just provide the Future trait. |
908 | let impl_bound = WhereClause::Implemented(TraitRef { | 957 | let impl_bound = Binders::new( |
909 | trait_id: to_chalk_trait_id(future_trait), | 958 | 0, |
910 | substitution: Substitution::empty(), | 959 | WhereClause::Implemented(TraitRef { |
911 | }); | 960 | trait_id: to_chalk_trait_id(future_trait), |
961 | substitution: Substitution::empty(), | ||
962 | }), | ||
963 | ); | ||
912 | Some(vec![impl_bound]) | 964 | Some(vec![impl_bound]) |
913 | } else { | 965 | } else { |
914 | None | 966 | None |
@@ -945,7 +997,7 @@ impl Ty { | |||
945 | .generic_predicates(id.parent) | 997 | .generic_predicates(id.parent) |
946 | .into_iter() | 998 | .into_iter() |
947 | .map(|pred| pred.clone().subst(&substs)) | 999 | .map(|pred| pred.clone().subst(&substs)) |
948 | .filter(|wc| match &wc { | 1000 | .filter(|wc| match &wc.skip_binders() { |
949 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, | 1001 | WhereClause::Implemented(tr) => tr.self_type_parameter() == self, |
950 | WhereClause::AliasEq(AliasEq { | 1002 | WhereClause::AliasEq(AliasEq { |
951 | alias: AliasTy::Projection(proj), | 1003 | alias: AliasTy::Projection(proj), |
@@ -1094,8 +1146,8 @@ impl TypeWalk for Ty { | |||
1094 | t.walk(f); | 1146 | t.walk(f); |
1095 | } | 1147 | } |
1096 | } | 1148 | } |
1097 | TyKind::Dyn(predicates) => { | 1149 | TyKind::Dyn(dyn_ty) => { |
1098 | for p in predicates.iter() { | 1150 | for p in dyn_ty.bounds.value.interned().iter() { |
1099 | p.walk(f); | 1151 | p.walk(f); |
1100 | } | 1152 | } |
1101 | } | 1153 | } |
@@ -1122,8 +1174,8 @@ impl TypeWalk for Ty { | |||
1122 | TyKind::Alias(AliasTy::Projection(p_ty)) => { | 1174 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1123 | p_ty.substitution.walk_mut_binders(f, binders); | 1175 | p_ty.substitution.walk_mut_binders(f, binders); |
1124 | } | 1176 | } |
1125 | TyKind::Dyn(predicates) => { | 1177 | TyKind::Dyn(dyn_ty) => { |
1126 | for p in make_mut_slice(predicates) { | 1178 | for p in make_mut_slice(&mut dyn_ty.bounds.value.0) { |
1127 | p.walk_mut_binders(f, binders.shifted_in()); | 1179 | p.walk_mut_binders(f, binders.shifted_in()); |
1128 | } | 1180 | } |
1129 | } | 1181 | } |
@@ -1173,7 +1225,7 @@ pub struct ReturnTypeImplTraits { | |||
1173 | 1225 | ||
1174 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 1226 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
1175 | pub(crate) struct ReturnTypeImplTrait { | 1227 | pub(crate) struct ReturnTypeImplTrait { |
1176 | pub(crate) bounds: Binders<Vec<WhereClause>>, | 1228 | pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, |
1177 | } | 1229 | } |
1178 | 1230 | ||
1179 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | 1231 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { |