aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-04-05 16:45:18 +0100
committerFlorian Diebold <[email protected]>2021-04-05 18:19:18 +0100
commitad20f00844cec9c794e34869be163673ebbed182 (patch)
tree0f37d26295bc9a8372d09df1612bd08a6d19ff72 /crates
parent69714d36e6617800f3edea174f5d6f76c985ad4c (diff)
Use VariableKinds in Binders
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/builder.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs4
-rw-r--r--crates/hir_ty/src/lib.rs26
-rw-r--r--crates/hir_ty/src/lower.rs82
-rw-r--r--crates/hir_ty/src/traits/chalk.rs10
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs22
-rw-r--r--crates/hir_ty/src/types.rs45
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
195impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { 195impl<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>;
66pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 66pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
67pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 67pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
68 68
69pub type VariableKind = chalk_ir::VariableKind<Interner>;
70pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
69pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; 71pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
70 72
71pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 73pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
@@ -126,22 +128,26 @@ impl<T> Binders<T> {
126 } 128 }
127} 129}
128 130
129impl<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
136impl<T: TypeWalk> Binders<T> { 131impl<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
140pub 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
145impl TraitRef { 151impl 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 {
1058fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1053fn 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
1087fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 1082fn 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
1139fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1134fn 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
1146fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1141fn 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.
1213pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { 1208pub(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
1221pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { 1216pub(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
1230pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1227pub(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
1250pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1247pub(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
1268pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1265pub(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
1303fn 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
13use crate::{ 13use 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)]
300pub struct Binders<T> { 300pub 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
305impl<T> Binders<T> { 306impl<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
346impl<T: Clone> Binders<&T> {
347 pub fn cloned(&self) -> Binders<T> {
348 Binders::new(self.binders.clone(), self.value.clone())
349 }
350}
351
352impl<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)]
341pub struct TraitRef { 362pub struct TraitRef {