Use VariableKinds in Binders

This commit is contained in:
Florian Diebold 2021-04-05 17:45:18 +02:00
parent 69714d36e6
commit ad20f00844
7 changed files with 107 additions and 84 deletions

View file

@ -194,7 +194,7 @@ impl TyBuilder<TypeAliasId> {
impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> {
fn subst_binders(b: Binders<T>) -> Self { fn subst_binders(b: Binders<T>) -> Self {
let param_count = b.num_binders; let param_count = b.binders.len(&Interner);
TyBuilder::new(b, param_count) TyBuilder::new(b, param_count)
} }

View file

@ -849,7 +849,7 @@ impl<'a> InferenceContext<'a> {
self.write_method_resolution(tgt_expr, func); self.write_method_resolution(tgt_expr, func);
(ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
} }
None => (receiver_ty, Binders::new(0, self.err_ty()), None), None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
}; };
let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
let method_ty = method_ty.subst(&substs); let method_ty = method_ty.subst(&substs);
@ -951,7 +951,7 @@ impl<'a> InferenceContext<'a> {
for predicate in generic_predicates.iter() { for predicate in generic_predicates.iter() {
let (predicate, binders) = let (predicate, binders) =
predicate.clone().subst(parameters).into_value_and_skipped_binders(); predicate.clone().subst(parameters).into_value_and_skipped_binders();
always!(binders == 0); // quantified where clauses not yet handled always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
self.push_obligation(predicate.cast(&Interner)); self.push_obligation(predicate.cast(&Interner));
} }
// add obligation for trait implementation, if this is a trait method // add obligation for trait implementation, if this is a trait method

View file

@ -66,6 +66,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
pub type VariableKind = chalk_ir::VariableKind<Interner>;
pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
pub type ChalkTraitId = chalk_ir::TraitId<Interner>; pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
@ -126,22 +128,26 @@ impl<T> Binders<T> {
} }
} }
impl<T: Clone> Binders<&T> {
pub fn cloned(&self) -> Binders<T> {
let (value, binders) = self.into_value_and_skipped_binders();
Binders::new(binders, value.clone())
}
}
impl<T: TypeWalk> Binders<T> { impl<T: TypeWalk> Binders<T> {
/// Substitutes all variables. /// Substitutes all variables.
pub fn subst(self, subst: &Substitution) -> T { pub fn subst(self, subst: &Substitution) -> T {
let (value, binders) = self.into_value_and_skipped_binders(); let (value, binders) = self.into_value_and_skipped_binders();
assert_eq!(subst.len(&Interner), binders); assert_eq!(subst.len(&Interner), binders.len(&Interner));
value.subst_bound_vars(subst) value.subst_bound_vars(subst)
} }
} }
pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
Binders::new(
VariableKinds::from_iter(
&Interner,
std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
.take(num_vars),
),
value,
)
}
impl TraitRef { impl TraitRef {
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
&self.substitution.at(interner, 0).assert_ty_ref(interner) &self.substitution.at(interner, 0).assert_ty_ref(interner)
@ -407,8 +413,8 @@ impl Ty {
// This is only used by type walking. // This is only used by type walking.
// Parameters will be walked outside, and projection predicate is not used. // Parameters will be walked outside, and projection predicate is not used.
// So just provide the Future trait. // So just provide the Future trait.
let impl_bound = Binders::new( let impl_bound = Binders::empty(
0, &Interner,
WhereClause::Implemented(TraitRef { WhereClause::Implemented(TraitRef {
trait_id: to_chalk_trait_id(future_trait), trait_id: to_chalk_trait_id(future_trait),
substitution: Substitution::empty(&Interner), substitution: Substitution::empty(&Interner),

View file

@ -31,7 +31,7 @@ use crate::{
traits::chalk::{Interner, ToChalk}, traits::chalk::{Interner, ToChalk},
utils::{ utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
variant_data, variant_data, Generics,
}, },
AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
@ -196,7 +196,7 @@ impl<'a> TyLoweringContext<'a> {
bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
) )
}); });
let bounds = Binders::new(1, bounds); let bounds = crate::make_only_type_binders(1, bounds);
TyKind::Dyn(DynTy { bounds }).intern(&Interner) TyKind::Dyn(DynTy { bounds }).intern(&Interner)
} }
TypeRef::ImplTrait(bounds) => { TypeRef::ImplTrait(bounds) => {
@ -209,9 +209,9 @@ impl<'a> TyLoweringContext<'a> {
// this dance is to make sure the data is in the right // this dance is to make sure the data is in the right
// place even if we encounter more opaque types while // place even if we encounter more opaque types while
// lowering the bounds // lowering the bounds
self.opaque_type_data self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
.borrow_mut() bounds: crate::make_only_type_binders(1, Vec::new()),
.push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); });
// We don't want to lower the bounds inside the binders // We don't want to lower the bounds inside the binders
// we're currently in, because they don't end up inside // we're currently in, because they don't end up inside
// those binders. E.g. when we have `impl Trait<impl // those binders. E.g. when we have `impl Trait<impl
@ -380,7 +380,7 @@ impl<'a> TyLoweringContext<'a> {
TyKind::Error.intern(&Interner) TyKind::Error.intern(&Interner)
} else { } else {
let dyn_ty = DynTy { let dyn_ty = DynTy {
bounds: Binders::new( bounds: crate::make_only_type_binders(
1, 1,
QuantifiedWhereClauses::from_iter( QuantifiedWhereClauses::from_iter(
&Interner, &Interner,
@ -787,7 +787,7 @@ impl<'a> TyLoweringContext<'a> {
let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
}); });
ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } ReturnTypeImplTrait { bounds: crate::make_only_type_binders(1, predicates) }
} }
} }
@ -884,7 +884,7 @@ pub(crate) fn field_types_query(
let ctx = let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
for (field_id, field_data) in var_data.fields().iter() { for (field_id, field_data) in var_data.fields().iter() {
res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) res.insert(field_id, make_binders(&generics, ctx.lower_ty(&field_data.type_ref)))
} }
Arc::new(res) Arc::new(res)
} }
@ -918,9 +918,7 @@ pub(crate) fn generic_predicates_for_param_query(
}, },
WherePredicate::Lifetime { .. } => false, WherePredicate::Lifetime { .. } => false,
}) })
.flat_map(|pred| { .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p)))
ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
})
.collect() .collect()
} }
@ -991,9 +989,7 @@ pub(crate) fn generic_predicates_query(
let generics = generics(db.upcast(), def); let generics = generics(db.upcast(), def);
resolver resolver
.where_predicates_in_scope() .where_predicates_in_scope()
.flat_map(|pred| { .flat_map(|pred| ctx.lower_where_predicate(pred, false).map(|p| make_binders(&generics, p)))
ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
})
.collect() .collect()
} }
@ -1030,7 +1026,7 @@ pub(crate) fn generic_defaults_query(
DebruijnIndex::INNERMOST, DebruijnIndex::INNERMOST,
); );
Binders::new(idx, ty) crate::make_only_type_binders(idx, ty)
}) })
.collect(); .collect();
@ -1043,14 +1039,13 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
let ctx_params = TyLoweringContext::new(db, &resolver) let ctx_params = TyLoweringContext::new(db, &resolver)
.with_impl_trait_mode(ImplTraitLoweringMode::Variable) .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
.with_type_param_mode(TypeParamLoweringMode::Variable); .with_type_param_mode(TypeParamLoweringMode::Variable);
let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
let ctx_ret = TyLoweringContext::new(db, &resolver) let ctx_ret = TyLoweringContext::new(db, &resolver)
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
.with_type_param_mode(TypeParamLoweringMode::Variable); .with_type_param_mode(TypeParamLoweringMode::Variable);
let ret = (&ctx_ret).lower_ty(&data.ret_type); let ret = ctx_ret.lower_ty(&data.ret_type);
let generics = generics(db.upcast(), def.into()); let generics = generics(db.upcast(), def.into());
let num_binders = generics.len(); make_binders(&generics, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
} }
/// Build the declared type of a function. This should not need to look at the /// 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 {
fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
let generics = generics(db.upcast(), def.into()); let generics = generics(db.upcast(), def.into());
let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
Binders::new( make_binders(
substs.len(&Interner), &generics,
TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
) )
} }
@ -1072,7 +1067,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
let ctx = let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) make_binders(&generics, ctx.lower_ty(&data.type_ref))
} }
/// Build the declared type of a static. /// Build the declared type of a static.
@ -1081,7 +1076,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
let resolver = def.resolver(db.upcast()); let resolver = def.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver); let ctx = TyLoweringContext::new(db, &resolver);
Binders::new(0, ctx.lower_ty(&data.type_ref)) Binders::empty(&Interner, ctx.lower_ty(&data.type_ref))
} }
fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 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
} }
let generics = generics(db.upcast(), def.into()); let generics = generics(db.upcast(), def.into());
let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
Binders::new( make_binders(
substs.len(&Interner), &generics,
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
) )
} }
@ -1130,17 +1125,17 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
} }
let generics = generics(db.upcast(), def.parent.into()); let generics = generics(db.upcast(), def.parent.into());
let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
Binders::new( make_binders(
substs.len(&Interner), &generics,
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
) )
} }
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
let generics = generics(db.upcast(), adt.into());
let b = TyBuilder::adt(db, adt); let b = TyBuilder::adt(db, adt);
let num_binders = b.remaining();
let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
Binders::new(num_binders, ty) make_binders(&generics, ty)
} }
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 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> {
let ctx = let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
if db.type_alias_data(t).is_extern { if db.type_alias_data(t).is_extern {
Binders::new(0, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner)) Binders::empty(&Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner))
} else { } else {
let type_ref = &db.type_alias_data(t).type_ref; let type_ref = &db.type_alias_data(t).type_ref;
let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
Binders::new(generics.len(), inner) make_binders(&generics, inner)
} }
} }
@ -1212,19 +1207,21 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V
/// namespace. /// namespace.
pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
match def { match def {
TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)), TyDefId::BuiltinType(it) => Binders::empty(&Interner, TyBuilder::builtin(it)),
TyDefId::AdtId(it) => type_for_adt(db, it), TyDefId::AdtId(it) => type_for_adt(db, it),
TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
} }
} }
pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
let num_binders = match *def { let generics = match *def {
TyDefId::BuiltinType(_) => 0, TyDefId::BuiltinType(_) => {
TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), return Binders::empty(&Interner, TyKind::Error.intern(&Interner))
TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), }
TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
}; };
Binders::new(num_binders, TyKind::Error.intern(&Interner)) make_binders(&generics, TyKind::Error.intern(&Interner))
} }
pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 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
let generics = generics(db.upcast(), impl_id.into()); let generics = generics(db.upcast(), impl_id.into());
let ctx = let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty)) make_binders(&generics, ctx.lower_ty(&impl_data.self_ty))
} }
pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
@ -1262,7 +1259,7 @@ pub(crate) fn impl_self_ty_recover(
impl_id: &ImplId, impl_id: &ImplId,
) -> Binders<Ty> { ) -> Binders<Ty> {
let generics = generics(db.upcast(), (*impl_id).into()); let generics = generics(db.upcast(), (*impl_id).into());
Binders::new(generics.len(), TyKind::Error.intern(&Interner)) make_binders(&generics, TyKind::Error.intern(&Interner))
} }
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 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(
.with_type_param_mode(TypeParamLoweringMode::Variable); .with_type_param_mode(TypeParamLoweringMode::Variable);
let _ret = (&ctx_ret).lower_ty(&data.ret_type); let _ret = (&ctx_ret).lower_ty(&data.ret_type);
let generics = generics(db.upcast(), def.into()); let generics = generics(db.upcast(), def.into());
let num_binders = generics.len();
let return_type_impl_traits = let return_type_impl_traits =
ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
if return_type_impl_traits.impl_traits.is_empty() { if return_type_impl_traits.impl_traits.is_empty() {
None None
} else { } else {
Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) Some(Arc::new(make_binders(&generics, return_type_impl_traits)))
} }
} }
@ -1303,3 +1299,7 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
hir_def::type_ref::Mutability::Mut => Mutability::Mut, hir_def::type_ref::Mutability::Mut => Mutability::Mut,
} }
} }
fn make_binders<T>(generics: &Generics, value: T) -> Binders<T> {
crate::make_only_type_binders(generics.len(), value)
}

View file

@ -184,7 +184,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
.db .db
.return_type_impl_traits(func) .return_type_impl_traits(func)
.expect("impl trait id without impl traits"); .expect("impl trait id without impl traits");
let data = &datas.skip_binders().impl_traits[idx as usize]; let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders();
let data = &datas.impl_traits[idx as usize];
let bound = OpaqueTyDatumBound { let bound = OpaqueTyDatumBound {
bounds: make_binders( bounds: make_binders(
data.bounds data.bounds
@ -197,8 +198,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
), ),
where_clauses: make_binders(vec![], 0), where_clauses: make_binders(vec![], 0),
}; };
let num_vars = datas.num_binders; chalk_ir::Binders::new(binders, bound)
make_binders(bound, num_vars)
} }
crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
if let Some((future_trait, future_output)) = self if let Some((future_trait, future_output)) = self
@ -626,7 +626,7 @@ fn type_alias_associated_ty_value(
let value = rust_ir::AssociatedTyValue { let value = rust_ir::AssociatedTyValue {
impl_id: impl_id.to_chalk(db), impl_id: impl_id.to_chalk(db),
associated_ty_id: to_assoc_type_id(assoc_ty), associated_ty_id: to_assoc_type_id(assoc_ty),
value: make_binders(value_bound, binders), value: chalk_ir::Binders::new(binders, value_bound),
}; };
Arc::new(value) Arc::new(value)
} }
@ -656,7 +656,7 @@ pub(crate) fn fn_def_datum_query(
let datum = FnDefDatum { let datum = FnDefDatum {
id: fn_def_id, id: fn_def_id,
sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs }, sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
binders: make_binders(bound, binders), binders: chalk_ir::Binders::new(binders, bound),
}; };
Arc::new(datum) Arc::new(datum)
} }

View file

@ -99,7 +99,7 @@ impl ToChalk for Ty {
bounds.interned().iter().cloned().map(|p| p.to_chalk(db)), bounds.interned().iter().cloned().map(|p| p.to_chalk(db)),
); );
let bounded_ty = chalk_ir::DynTy { let bounded_ty = chalk_ir::DynTy {
bounds: make_binders(where_clauses, binders), bounds: chalk_ir::Binders::new(binders, where_clauses),
lifetime: LifetimeData::Static.intern(&Interner), lifetime: LifetimeData::Static.intern(&Interner),
}; };
chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
@ -149,7 +149,7 @@ impl ToChalk for Ty {
.map(|c| from_chalk(db, c.clone())); .map(|c| from_chalk(db, c.clone()));
TyKind::Dyn(crate::DynTy { TyKind::Dyn(crate::DynTy {
bounds: crate::Binders::new( bounds: crate::Binders::new(
1, where_clauses.bounds.binders.clone(),
crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), crate::QuantifiedWhereClauses::from_iter(&Interner, bounds),
), ),
}) })
@ -488,19 +488,12 @@ where
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
let (value, binders) = self.into_value_and_skipped_binders(); let (value, binders) = self.into_value_and_skipped_binders();
chalk_ir::Binders::new( chalk_ir::Binders::new(binders, value.to_chalk(db))
chalk_ir::VariableKinds::from_iter(
&Interner,
std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
.take(binders),
),
value.to_chalk(db),
)
} }
fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
let (v, b) = binders.into_value_and_skipped_binders(); let (v, b) = binders.into_value_and_skipped_binders();
crate::Binders::new(b.len(&Interner), from_chalk(db, v)) crate::Binders::new(b, from_chalk(db, v))
} }
} }
@ -552,7 +545,7 @@ pub(super) fn generic_predicate_to_inline_bound(
.map(|ty| ty.clone().to_chalk(db).cast(&Interner)) .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
.collect(); .collect();
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), binders)) Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
} }
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in {
@ -569,7 +562,10 @@ pub(super) fn generic_predicate_to_inline_bound(
associated_ty_id: projection_ty.associated_ty_id, associated_ty_id: projection_ty.associated_ty_id,
parameters: Vec::new(), // FIXME we don't support generic associated types yet parameters: Vec::new(), // FIXME we don't support generic associated types yet
}; };
Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), binders)) Some(chalk_ir::Binders::new(
binders,
rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
))
} }
_ => None, _ => None,
} }

View file

@ -12,7 +12,7 @@ use smallvec::SmallVec;
use crate::{ use crate::{
AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, VariableKinds,
}; };
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@ -286,7 +286,7 @@ impl Substitution {
Substitution(elements.into_iter().casted(interner).collect()) Substitution(elements.into_iter().casted(interner).collect())
} }
// We can hopefully add this to Chalk // Temporary helper functions, to be removed
pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution {
Substitution(interned) Substitution(interned)
} }
@ -296,46 +296,67 @@ impl Substitution {
} }
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub struct Binders<T> { pub struct Binders<T> {
pub num_binders: usize, /// The binders that quantify over the value.
pub binders: VariableKinds,
value: T, value: T,
} }
impl<T> Binders<T> { impl<T> Binders<T> {
pub fn new(num_binders: usize, value: T) -> Self { pub fn new(binders: VariableKinds, value: T) -> Self {
Self { num_binders, value } Self { binders, value }
} }
pub fn empty(_interner: &Interner, value: T) -> Self { pub fn empty(_interner: &Interner, value: T) -> Self {
Self { num_binders: 0, value } crate::make_only_type_binders(0, value)
} }
pub fn as_ref(&self) -> Binders<&T> { pub fn as_ref(&self) -> Binders<&T> {
Binders { num_binders: self.num_binders, value: &self.value } Binders { binders: self.binders.clone(), value: &self.value }
} }
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
Binders { num_binders: self.num_binders, value: f(self.value) } Binders { binders: self.binders, value: f(self.value) }
} }
pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) Some(Binders { binders: self.binders, value: f(self.value)? })
} }
pub fn skip_binders(&self) -> &T { pub fn skip_binders(&self) -> &T {
&self.value &self.value
} }
pub fn into_value_and_skipped_binders(self) -> (T, usize) { pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) {
(self.value, self.num_binders) (self.value, self.binders)
} }
/// Returns the number of binders.
pub fn len(&self, interner: &Interner) -> usize {
self.binders.len(interner)
}
// Temporary helper function, to be removed
pub fn skip_binders_mut(&mut self) -> &mut T { pub fn skip_binders_mut(&mut self) -> &mut T {
&mut self.value &mut self.value
} }
} }
impl<T: Clone> Binders<&T> {
pub fn cloned(&self) -> Binders<T> {
Binders::new(self.binders.clone(), self.value.clone())
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let Binders { ref binders, ref value } = *self;
write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?;
std::fmt::Debug::fmt(value, fmt)
}
}
/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct TraitRef { pub struct TraitRef {