diff options
author | Florian Diebold <[email protected]> | 2021-04-05 16:45:18 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-04-05 18:19:18 +0100 |
commit | ad20f00844cec9c794e34869be163673ebbed182 (patch) | |
tree | 0f37d26295bc9a8372d09df1612bd08a6d19ff72 /crates/hir_ty/src | |
parent | 69714d36e6617800f3edea174f5d6f76c985ad4c (diff) |
Use VariableKinds in Binders
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/builder.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 26 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 82 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 22 | ||||
-rw-r--r-- | crates/hir_ty/src/types.rs | 45 |
7 files changed, 107 insertions, 84 deletions
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs index 372621f73..7b8603fd7 100644 --- a/crates/hir_ty/src/builder.rs +++ b/crates/hir_ty/src/builder.rs | |||
@@ -194,7 +194,7 @@ impl TyBuilder<TypeAliasId> { | |||
194 | 194 | ||
195 | impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { | 195 | impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { |
196 | fn subst_binders(b: Binders<T>) -> Self { | 196 | fn subst_binders(b: Binders<T>) -> Self { |
197 | let param_count = b.num_binders; | 197 | let param_count = b.binders.len(&Interner); |
198 | TyBuilder::new(b, param_count) | 198 | TyBuilder::new(b, param_count) |
199 | } | 199 | } |
200 | 200 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index ccaae53e9..d61ef65f2 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -849,7 +849,7 @@ impl<'a> InferenceContext<'a> { | |||
849 | self.write_method_resolution(tgt_expr, func); | 849 | self.write_method_resolution(tgt_expr, func); |
850 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 850 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
851 | } | 851 | } |
852 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), | 852 | None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None), |
853 | }; | 853 | }; |
854 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 854 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
855 | let method_ty = method_ty.subst(&substs); | 855 | let method_ty = method_ty.subst(&substs); |
@@ -951,7 +951,7 @@ impl<'a> InferenceContext<'a> { | |||
951 | for predicate in generic_predicates.iter() { | 951 | for predicate in generic_predicates.iter() { |
952 | let (predicate, binders) = | 952 | let (predicate, binders) = |
953 | predicate.clone().subst(parameters).into_value_and_skipped_binders(); | 953 | predicate.clone().subst(parameters).into_value_and_skipped_binders(); |
954 | always!(binders == 0); // quantified where clauses not yet handled | 954 | always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled |
955 | self.push_obligation(predicate.cast(&Interner)); | 955 | self.push_obligation(predicate.cast(&Interner)); |
956 | } | 956 | } |
957 | // add obligation for trait implementation, if this is a trait method | 957 | // add obligation for trait implementation, if this is a trait method |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 61b5cf269..86973c7ed 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -66,6 +66,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>; | |||
66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | 67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; |
68 | 68 | ||
69 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | ||
70 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | ||
69 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 71 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
70 | 72 | ||
71 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | 73 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; |
@@ -126,22 +128,26 @@ impl<T> Binders<T> { | |||
126 | } | 128 | } |
127 | } | 129 | } |
128 | 130 | ||
129 | impl<T: Clone> Binders<&T> { | ||
130 | pub fn cloned(&self) -> Binders<T> { | ||
131 | let (value, binders) = self.into_value_and_skipped_binders(); | ||
132 | Binders::new(binders, value.clone()) | ||
133 | } | ||
134 | } | ||
135 | |||
136 | impl<T: TypeWalk> Binders<T> { | 131 | impl<T: TypeWalk> Binders<T> { |
137 | /// Substitutes all variables. | 132 | /// Substitutes all variables. |
138 | pub fn subst(self, subst: &Substitution) -> T { | 133 | pub fn subst(self, subst: &Substitution) -> T { |
139 | let (value, binders) = self.into_value_and_skipped_binders(); | 134 | let (value, binders) = self.into_value_and_skipped_binders(); |
140 | assert_eq!(subst.len(&Interner), binders); | 135 | assert_eq!(subst.len(&Interner), binders.len(&Interner)); |
141 | value.subst_bound_vars(subst) | 136 | value.subst_bound_vars(subst) |
142 | } | 137 | } |
143 | } | 138 | } |
144 | 139 | ||
140 | pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> { | ||
141 | Binders::new( | ||
142 | VariableKinds::from_iter( | ||
143 | &Interner, | ||
144 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
145 | .take(num_vars), | ||
146 | ), | ||
147 | value, | ||
148 | ) | ||
149 | } | ||
150 | |||
145 | impl TraitRef { | 151 | impl TraitRef { |
146 | pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { | 152 | pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { |
147 | &self.substitution.at(interner, 0).assert_ty_ref(interner) | 153 | &self.substitution.at(interner, 0).assert_ty_ref(interner) |
@@ -407,8 +413,8 @@ impl Ty { | |||
407 | // This is only used by type walking. | 413 | // This is only used by type walking. |
408 | // Parameters will be walked outside, and projection predicate is not used. | 414 | // Parameters will be walked outside, and projection predicate is not used. |
409 | // So just provide the Future trait. | 415 | // So just provide the Future trait. |
410 | let impl_bound = Binders::new( | 416 | let impl_bound = Binders::empty( |
411 | 0, | 417 | &Interner, |
412 | WhereClause::Implemented(TraitRef { | 418 | WhereClause::Implemented(TraitRef { |
413 | trait_id: to_chalk_trait_id(future_trait), | 419 | trait_id: to_chalk_trait_id(future_trait), |
414 | substitution: Substitution::empty(&Interner), | 420 | substitution: Substitution::empty(&Interner), |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 19465b2ed..59d2a157f 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -31,7 +31,7 @@ use crate::{ | |||
31 | traits::chalk::{Interner, ToChalk}, | 31 | traits::chalk::{Interner, ToChalk}, |
32 | utils::{ | 32 | utils::{ |
33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
34 | variant_data, | 34 | variant_data, Generics, |
35 | }, | 35 | }, |
36 | AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, | 36 | AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, |
37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, | 37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, |
@@ -196,7 +196,7 @@ impl<'a> TyLoweringContext<'a> { | |||
196 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), | 196 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), |
197 | ) | 197 | ) |
198 | }); | 198 | }); |
199 | let bounds = Binders::new(1, bounds); | 199 | let bounds = crate::make_only_type_binders(1, bounds); |
200 | TyKind::Dyn(DynTy { bounds }).intern(&Interner) | 200 | TyKind::Dyn(DynTy { bounds }).intern(&Interner) |
201 | } | 201 | } |
202 | TypeRef::ImplTrait(bounds) => { | 202 | TypeRef::ImplTrait(bounds) => { |
@@ -209,9 +209,9 @@ impl<'a> TyLoweringContext<'a> { | |||
209 | // this dance is to make sure the data is in the right | 209 | // this dance is to make sure the data is in the right |
210 | // place even if we encounter more opaque types while | 210 | // place even if we encounter more opaque types while |
211 | // lowering the bounds | 211 | // lowering the bounds |
212 | self.opaque_type_data | 212 | self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait { |
213 | .borrow_mut() | 213 | bounds: crate::make_only_type_binders(1, Vec::new()), |
214 | .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); | 214 | }); |
215 | // We don't want to lower the bounds inside the binders | 215 | // We don't want to lower the bounds inside the binders |
216 | // we're currently in, because they don't end up inside | 216 | // we're currently in, because they don't end up inside |
217 | // those binders. E.g. when we have `impl Trait<impl | 217 | // those binders. E.g. when we have `impl Trait<impl |
@@ -380,7 +380,7 @@ impl<'a> TyLoweringContext<'a> { | |||
380 | TyKind::Error.intern(&Interner) | 380 | TyKind::Error.intern(&Interner) |
381 | } else { | 381 | } else { |
382 | let dyn_ty = DynTy { | 382 | let dyn_ty = DynTy { |
383 | bounds: Binders::new( | 383 | bounds: crate::make_only_type_binders( |
384 | 1, | 384 | 1, |
385 | QuantifiedWhereClauses::from_iter( | 385 | QuantifiedWhereClauses::from_iter( |
386 | &Interner, | 386 | &Interner, |
@@ -787,7 +787,7 @@ impl<'a> TyLoweringContext<'a> { | |||
787 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 787 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
788 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() | 788 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() |
789 | }); | 789 | }); |
790 | ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } | 790 | ReturnTypeImplTrait { bounds: crate::make_only_type_binders(1, predicates) } |
791 | } | 791 | } |
792 | } | 792 | } |
793 | 793 | ||
@@ -884,7 +884,7 @@ pub(crate) fn field_types_query( | |||
884 | let ctx = | 884 | let ctx = |
885 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 885 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
886 | for (field_id, field_data) in var_data.fields().iter() { | 886 | for (field_id, field_data) in var_data.fields().iter() { |
887 | res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) | 887 | res.insert(field_id, make_binders(&generics, ctx.lower_ty(&field_data.type_ref))) |
888 | } | 888 | } |
889 | Arc::new(res) | 889 | Arc::new(res) |
890 | } | 890 | } |
@@ -918,9 +918,7 @@ pub(crate) fn generic_predicates_for_param_query( | |||
918 | }, | 918 | }, |
919 | WherePredicate::Lifetime { .. } => false, | 919 | WherePredicate::Lifetime { .. } => false, |
920 | }) | 920 | }) |
921 | .flat_map(|pred| { | 921 | .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p))) |
922 | ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p)) | ||
923 | }) | ||
924 | .collect() | 922 | .collect() |
925 | } | 923 | } |
926 | 924 | ||
@@ -991,9 +989,7 @@ pub(crate) fn generic_predicates_query( | |||
991 | let generics = generics(db.upcast(), def); | 989 | let generics = generics(db.upcast(), def); |
992 | resolver | 990 | resolver |
993 | .where_predicates_in_scope() | 991 | .where_predicates_in_scope() |
994 | .flat_map(|pred| { | 992 | .flat_map(|pred| ctx.lower_where_predicate(pred, false).map(|p| make_binders(&generics, p))) |
995 | ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p)) | ||
996 | }) | ||
997 | .collect() | 993 | .collect() |
998 | } | 994 | } |
999 | 995 | ||
@@ -1030,7 +1026,7 @@ pub(crate) fn generic_defaults_query( | |||
1030 | DebruijnIndex::INNERMOST, | 1026 | DebruijnIndex::INNERMOST, |
1031 | ); | 1027 | ); |
1032 | 1028 | ||
1033 | Binders::new(idx, ty) | 1029 | crate::make_only_type_binders(idx, ty) |
1034 | }) | 1030 | }) |
1035 | .collect(); | 1031 | .collect(); |
1036 | 1032 | ||
@@ -1043,14 +1039,13 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1043 | let ctx_params = TyLoweringContext::new(db, &resolver) | 1039 | let ctx_params = TyLoweringContext::new(db, &resolver) |
1044 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) | 1040 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) |
1045 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1041 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1046 | let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); | 1042 | let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>(); |
1047 | let ctx_ret = TyLoweringContext::new(db, &resolver) | 1043 | let ctx_ret = TyLoweringContext::new(db, &resolver) |
1048 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) | 1044 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) |
1049 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1045 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1050 | let ret = (&ctx_ret).lower_ty(&data.ret_type); | 1046 | let ret = ctx_ret.lower_ty(&data.ret_type); |
1051 | let generics = generics(db.upcast(), def.into()); | 1047 | let generics = generics(db.upcast(), def.into()); |
1052 | let num_binders = generics.len(); | 1048 | make_binders(&generics, CallableSig::from_params_and_return(params, ret, data.is_varargs())) |
1053 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs())) | ||
1054 | } | 1049 | } |
1055 | 1050 | ||
1056 | /// Build the declared type of a function. This should not need to look at the | 1051 | /// Build the declared type of a function. This should not need to look at the |
@@ -1058,8 +1053,8 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1058 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1053 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1059 | let generics = generics(db.upcast(), def.into()); | 1054 | let generics = generics(db.upcast(), def.into()); |
1060 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1055 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1061 | Binders::new( | 1056 | make_binders( |
1062 | substs.len(&Interner), | 1057 | &generics, |
1063 | TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), | 1058 | TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), |
1064 | ) | 1059 | ) |
1065 | } | 1060 | } |
@@ -1072,7 +1067,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { | |||
1072 | let ctx = | 1067 | let ctx = |
1073 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1068 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1074 | 1069 | ||
1075 | Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) | 1070 | make_binders(&generics, ctx.lower_ty(&data.type_ref)) |
1076 | } | 1071 | } |
1077 | 1072 | ||
1078 | /// Build the declared type of a static. | 1073 | /// Build the declared type of a static. |
@@ -1081,7 +1076,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> { | |||
1081 | let resolver = def.resolver(db.upcast()); | 1076 | let resolver = def.resolver(db.upcast()); |
1082 | let ctx = TyLoweringContext::new(db, &resolver); | 1077 | let ctx = TyLoweringContext::new(db, &resolver); |
1083 | 1078 | ||
1084 | Binders::new(0, ctx.lower_ty(&data.type_ref)) | 1079 | Binders::empty(&Interner, ctx.lower_ty(&data.type_ref)) |
1085 | } | 1080 | } |
1086 | 1081 | ||
1087 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { | 1082 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { |
@@ -1103,8 +1098,8 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1103 | } | 1098 | } |
1104 | let generics = generics(db.upcast(), def.into()); | 1099 | let generics = generics(db.upcast(), def.into()); |
1105 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1100 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1106 | Binders::new( | 1101 | make_binders( |
1107 | substs.len(&Interner), | 1102 | &generics, |
1108 | TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), | 1103 | TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), |
1109 | ) | 1104 | ) |
1110 | } | 1105 | } |
@@ -1130,17 +1125,17 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1130 | } | 1125 | } |
1131 | let generics = generics(db.upcast(), def.parent.into()); | 1126 | let generics = generics(db.upcast(), def.parent.into()); |
1132 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); | 1127 | let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); |
1133 | Binders::new( | 1128 | make_binders( |
1134 | substs.len(&Interner), | 1129 | &generics, |
1135 | TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), | 1130 | TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), |
1136 | ) | 1131 | ) |
1137 | } | 1132 | } |
1138 | 1133 | ||
1139 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1134 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
1135 | let generics = generics(db.upcast(), adt.into()); | ||
1140 | let b = TyBuilder::adt(db, adt); | 1136 | let b = TyBuilder::adt(db, adt); |
1141 | let num_binders = b.remaining(); | ||
1142 | let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); | 1137 | let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); |
1143 | Binders::new(num_binders, ty) | 1138 | make_binders(&generics, ty) |
1144 | } | 1139 | } |
1145 | 1140 | ||
1146 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | 1141 | fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { |
@@ -1149,11 +1144,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1149 | let ctx = | 1144 | let ctx = |
1150 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1145 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1151 | if db.type_alias_data(t).is_extern { | 1146 | if db.type_alias_data(t).is_extern { |
1152 | Binders::new(0, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner)) | 1147 | Binders::empty(&Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner)) |
1153 | } else { | 1148 | } else { |
1154 | let type_ref = &db.type_alias_data(t).type_ref; | 1149 | let type_ref = &db.type_alias_data(t).type_ref; |
1155 | let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); | 1150 | let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); |
1156 | Binders::new(generics.len(), inner) | 1151 | make_binders(&generics, inner) |
1157 | } | 1152 | } |
1158 | } | 1153 | } |
1159 | 1154 | ||
@@ -1212,19 +1207,21 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V | |||
1212 | /// namespace. | 1207 | /// namespace. |
1213 | pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { | 1208 | pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { |
1214 | match def { | 1209 | match def { |
1215 | TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)), | 1210 | TyDefId::BuiltinType(it) => Binders::empty(&Interner, TyBuilder::builtin(it)), |
1216 | TyDefId::AdtId(it) => type_for_adt(db, it), | 1211 | TyDefId::AdtId(it) => type_for_adt(db, it), |
1217 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), | 1212 | TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), |
1218 | } | 1213 | } |
1219 | } | 1214 | } |
1220 | 1215 | ||
1221 | pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { | 1216 | pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { |
1222 | let num_binders = match *def { | 1217 | let generics = match *def { |
1223 | TyDefId::BuiltinType(_) => 0, | 1218 | TyDefId::BuiltinType(_) => { |
1224 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), | 1219 | return Binders::empty(&Interner, TyKind::Error.intern(&Interner)) |
1225 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), | 1220 | } |
1221 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()), | ||
1222 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()), | ||
1226 | }; | 1223 | }; |
1227 | Binders::new(num_binders, TyKind::Error.intern(&Interner)) | 1224 | make_binders(&generics, TyKind::Error.intern(&Interner)) |
1228 | } | 1225 | } |
1229 | 1226 | ||
1230 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { | 1227 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { |
@@ -1244,7 +1241,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde | |||
1244 | let generics = generics(db.upcast(), impl_id.into()); | 1241 | let generics = generics(db.upcast(), impl_id.into()); |
1245 | let ctx = | 1242 | let ctx = |
1246 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1243 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1247 | Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty)) | 1244 | make_binders(&generics, ctx.lower_ty(&impl_data.self_ty)) |
1248 | } | 1245 | } |
1249 | 1246 | ||
1250 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { | 1247 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { |
@@ -1262,7 +1259,7 @@ pub(crate) fn impl_self_ty_recover( | |||
1262 | impl_id: &ImplId, | 1259 | impl_id: &ImplId, |
1263 | ) -> Binders<Ty> { | 1260 | ) -> Binders<Ty> { |
1264 | let generics = generics(db.upcast(), (*impl_id).into()); | 1261 | let generics = generics(db.upcast(), (*impl_id).into()); |
1265 | Binders::new(generics.len(), TyKind::Error.intern(&Interner)) | 1262 | make_binders(&generics, TyKind::Error.intern(&Interner)) |
1266 | } | 1263 | } |
1267 | 1264 | ||
1268 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { | 1265 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { |
@@ -1287,13 +1284,12 @@ pub(crate) fn return_type_impl_traits( | |||
1287 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1284 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1288 | let _ret = (&ctx_ret).lower_ty(&data.ret_type); | 1285 | let _ret = (&ctx_ret).lower_ty(&data.ret_type); |
1289 | let generics = generics(db.upcast(), def.into()); | 1286 | let generics = generics(db.upcast(), def.into()); |
1290 | let num_binders = generics.len(); | ||
1291 | let return_type_impl_traits = | 1287 | let return_type_impl_traits = |
1292 | ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; | 1288 | ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; |
1293 | if return_type_impl_traits.impl_traits.is_empty() { | 1289 | if return_type_impl_traits.impl_traits.is_empty() { |
1294 | None | 1290 | None |
1295 | } else { | 1291 | } else { |
1296 | Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) | 1292 | Some(Arc::new(make_binders(&generics, return_type_impl_traits))) |
1297 | } | 1293 | } |
1298 | } | 1294 | } |
1299 | 1295 | ||
@@ -1303,3 +1299,7 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut | |||
1303 | hir_def::type_ref::Mutability::Mut => Mutability::Mut, | 1299 | hir_def::type_ref::Mutability::Mut => Mutability::Mut, |
1304 | } | 1300 | } |
1305 | } | 1301 | } |
1302 | |||
1303 | fn make_binders<T>(generics: &Generics, value: T) -> Binders<T> { | ||
1304 | crate::make_only_type_binders(generics.len(), value) | ||
1305 | } | ||
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 47867f77e..dff87ef70 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -184,7 +184,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
184 | .db | 184 | .db |
185 | .return_type_impl_traits(func) | 185 | .return_type_impl_traits(func) |
186 | .expect("impl trait id without impl traits"); | 186 | .expect("impl trait id without impl traits"); |
187 | let data = &datas.skip_binders().impl_traits[idx as usize]; | 187 | let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders(); |
188 | let data = &datas.impl_traits[idx as usize]; | ||
188 | let bound = OpaqueTyDatumBound { | 189 | let bound = OpaqueTyDatumBound { |
189 | bounds: make_binders( | 190 | bounds: make_binders( |
190 | data.bounds | 191 | data.bounds |
@@ -197,8 +198,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
197 | ), | 198 | ), |
198 | where_clauses: make_binders(vec![], 0), | 199 | where_clauses: make_binders(vec![], 0), |
199 | }; | 200 | }; |
200 | let num_vars = datas.num_binders; | 201 | chalk_ir::Binders::new(binders, bound) |
201 | make_binders(bound, num_vars) | ||
202 | } | 202 | } |
203 | crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { | 203 | crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
204 | if let Some((future_trait, future_output)) = self | 204 | if let Some((future_trait, future_output)) = self |
@@ -626,7 +626,7 @@ fn type_alias_associated_ty_value( | |||
626 | let value = rust_ir::AssociatedTyValue { | 626 | let value = rust_ir::AssociatedTyValue { |
627 | impl_id: impl_id.to_chalk(db), | 627 | impl_id: impl_id.to_chalk(db), |
628 | associated_ty_id: to_assoc_type_id(assoc_ty), | 628 | associated_ty_id: to_assoc_type_id(assoc_ty), |
629 | value: make_binders(value_bound, binders), | 629 | value: chalk_ir::Binders::new(binders, value_bound), |
630 | }; | 630 | }; |
631 | Arc::new(value) | 631 | Arc::new(value) |
632 | } | 632 | } |
@@ -656,7 +656,7 @@ pub(crate) fn fn_def_datum_query( | |||
656 | let datum = FnDefDatum { | 656 | let datum = FnDefDatum { |
657 | id: fn_def_id, | 657 | id: fn_def_id, |
658 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs }, | 658 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs }, |
659 | binders: make_binders(bound, binders), | 659 | binders: chalk_ir::Binders::new(binders, bound), |
660 | }; | 660 | }; |
661 | Arc::new(datum) | 661 | Arc::new(datum) |
662 | } | 662 | } |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 72458f367..2c7407c7c 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -99,7 +99,7 @@ impl ToChalk for Ty { | |||
99 | bounds.interned().iter().cloned().map(|p| p.to_chalk(db)), | 99 | bounds.interned().iter().cloned().map(|p| p.to_chalk(db)), |
100 | ); | 100 | ); |
101 | let bounded_ty = chalk_ir::DynTy { | 101 | let bounded_ty = chalk_ir::DynTy { |
102 | bounds: make_binders(where_clauses, binders), | 102 | bounds: chalk_ir::Binders::new(binders, where_clauses), |
103 | lifetime: LifetimeData::Static.intern(&Interner), | 103 | lifetime: LifetimeData::Static.intern(&Interner), |
104 | }; | 104 | }; |
105 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) | 105 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) |
@@ -149,7 +149,7 @@ impl ToChalk for Ty { | |||
149 | .map(|c| from_chalk(db, c.clone())); | 149 | .map(|c| from_chalk(db, c.clone())); |
150 | TyKind::Dyn(crate::DynTy { | 150 | TyKind::Dyn(crate::DynTy { |
151 | bounds: crate::Binders::new( | 151 | bounds: crate::Binders::new( |
152 | 1, | 152 | where_clauses.bounds.binders.clone(), |
153 | crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), | 153 | crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), |
154 | ), | 154 | ), |
155 | }) | 155 | }) |
@@ -488,19 +488,12 @@ where | |||
488 | 488 | ||
489 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { | 489 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { |
490 | let (value, binders) = self.into_value_and_skipped_binders(); | 490 | let (value, binders) = self.into_value_and_skipped_binders(); |
491 | chalk_ir::Binders::new( | 491 | chalk_ir::Binders::new(binders, value.to_chalk(db)) |
492 | chalk_ir::VariableKinds::from_iter( | ||
493 | &Interner, | ||
494 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
495 | .take(binders), | ||
496 | ), | ||
497 | value.to_chalk(db), | ||
498 | ) | ||
499 | } | 492 | } |
500 | 493 | ||
501 | fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { | 494 | fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { |
502 | let (v, b) = binders.into_value_and_skipped_binders(); | 495 | let (v, b) = binders.into_value_and_skipped_binders(); |
503 | crate::Binders::new(b.len(&Interner), from_chalk(db, v)) | 496 | crate::Binders::new(b, from_chalk(db, v)) |
504 | } | 497 | } |
505 | } | 498 | } |
506 | 499 | ||
@@ -552,7 +545,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
552 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 545 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
553 | .collect(); | 546 | .collect(); |
554 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | 547 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; |
555 | Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), binders)) | 548 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) |
556 | } | 549 | } |
557 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 550 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
558 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { | 551 | if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { |
@@ -569,7 +562,10 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
569 | associated_ty_id: projection_ty.associated_ty_id, | 562 | associated_ty_id: projection_ty.associated_ty_id, |
570 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 563 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
571 | }; | 564 | }; |
572 | Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), binders)) | 565 | Some(chalk_ir::Binders::new( |
566 | binders, | ||
567 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
568 | )) | ||
573 | } | 569 | } |
574 | _ => None, | 570 | _ => None, |
575 | } | 571 | } |
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index 0e3dd511f..59678b45b 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs | |||
@@ -12,7 +12,7 @@ use smallvec::SmallVec; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, | 14 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, |
15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, | 15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, VariableKinds, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 18 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
@@ -286,7 +286,7 @@ impl Substitution { | |||
286 | Substitution(elements.into_iter().casted(interner).collect()) | 286 | Substitution(elements.into_iter().casted(interner).collect()) |
287 | } | 287 | } |
288 | 288 | ||
289 | // We can hopefully add this to Chalk | 289 | // Temporary helper functions, to be removed |
290 | pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { | 290 | pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { |
291 | Substitution(interned) | 291 | Substitution(interned) |
292 | } | 292 | } |
@@ -296,46 +296,67 @@ impl Substitution { | |||
296 | } | 296 | } |
297 | } | 297 | } |
298 | 298 | ||
299 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 299 | #[derive(Clone, PartialEq, Eq, Hash)] |
300 | pub struct Binders<T> { | 300 | pub struct Binders<T> { |
301 | pub num_binders: usize, | 301 | /// The binders that quantify over the value. |
302 | pub binders: VariableKinds, | ||
302 | value: T, | 303 | value: T, |
303 | } | 304 | } |
304 | 305 | ||
305 | impl<T> Binders<T> { | 306 | impl<T> Binders<T> { |
306 | pub fn new(num_binders: usize, value: T) -> Self { | 307 | pub fn new(binders: VariableKinds, value: T) -> Self { |
307 | Self { num_binders, value } | 308 | Self { binders, value } |
308 | } | 309 | } |
309 | 310 | ||
310 | pub fn empty(_interner: &Interner, value: T) -> Self { | 311 | pub fn empty(_interner: &Interner, value: T) -> Self { |
311 | Self { num_binders: 0, value } | 312 | crate::make_only_type_binders(0, value) |
312 | } | 313 | } |
313 | 314 | ||
314 | pub fn as_ref(&self) -> Binders<&T> { | 315 | pub fn as_ref(&self) -> Binders<&T> { |
315 | Binders { num_binders: self.num_binders, value: &self.value } | 316 | Binders { binders: self.binders.clone(), value: &self.value } |
316 | } | 317 | } |
317 | 318 | ||
318 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { | 319 | pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { |
319 | Binders { num_binders: self.num_binders, value: f(self.value) } | 320 | Binders { binders: self.binders, value: f(self.value) } |
320 | } | 321 | } |
321 | 322 | ||
322 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { | 323 | pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { |
323 | Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) | 324 | Some(Binders { binders: self.binders, value: f(self.value)? }) |
324 | } | 325 | } |
325 | 326 | ||
326 | pub fn skip_binders(&self) -> &T { | 327 | pub fn skip_binders(&self) -> &T { |
327 | &self.value | 328 | &self.value |
328 | } | 329 | } |
329 | 330 | ||
330 | pub fn into_value_and_skipped_binders(self) -> (T, usize) { | 331 | pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) { |
331 | (self.value, self.num_binders) | 332 | (self.value, self.binders) |
332 | } | 333 | } |
333 | 334 | ||
335 | /// Returns the number of binders. | ||
336 | pub fn len(&self, interner: &Interner) -> usize { | ||
337 | self.binders.len(interner) | ||
338 | } | ||
339 | |||
340 | // Temporary helper function, to be removed | ||
334 | pub fn skip_binders_mut(&mut self) -> &mut T { | 341 | pub fn skip_binders_mut(&mut self) -> &mut T { |
335 | &mut self.value | 342 | &mut self.value |
336 | } | 343 | } |
337 | } | 344 | } |
338 | 345 | ||
346 | impl<T: Clone> Binders<&T> { | ||
347 | pub fn cloned(&self) -> Binders<T> { | ||
348 | Binders::new(self.binders.clone(), self.value.clone()) | ||
349 | } | ||
350 | } | ||
351 | |||
352 | impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> { | ||
353 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { | ||
354 | let Binders { ref binders, ref value } = *self; | ||
355 | write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?; | ||
356 | std::fmt::Debug::fmt(value, fmt) | ||
357 | } | ||
358 | } | ||
359 | |||
339 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | 360 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. |
340 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 361 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
341 | pub struct TraitRef { | 362 | pub struct TraitRef { |