aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs105
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>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 63
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
65
64pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 66pub 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)]
138pub struct DynTy {
139 /// The unknown self type.
140 pub bounds: Binders<QuantifiedWhereClauses>,
141}
142
131pub type FnSig = chalk_ir::FnSig<Interner>; 143pub 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
502impl<T: Clone> Binders<&T> { 529impl<T: Clone> Binders<&T> {
@@ -610,6 +637,24 @@ impl TypeWalk for WhereClause {
610 } 637 }
611} 638}
612 639
640pub type QuantifiedWhereClause = Binders<WhereClause>;
641
642#[derive(Debug, Clone, PartialEq, Eq, Hash)]
643pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
644
645impl 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)]
620pub struct Canonical<T> { 665pub struct Canonical<T> {
621 pub value: T, 666 pub value: T,
622 pub kinds: Arc<[TyVariableKind]>, 667 pub binders: CanonicalVarKinds,
623} 668}
624 669
625impl<T> Canonical<T> { 670impl<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)]
1162pub(crate) struct ReturnTypeImplTrait { 1227pub(crate) struct ReturnTypeImplTrait {
1163 pub(crate) bounds: Binders<Vec<WhereClause>>, 1228 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1164} 1229}
1165 1230
1166pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 1231pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {