Skip to content

Commit ef9f6b6

Browse files
committed
Push binders at the start
1 parent c887f52 commit ef9f6b6

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

chalk-solve/src/clauses/builtin_traits/fn_family.rs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,35 @@ pub fn add_fn_trait_program_clauses<I: Interner>(
2323
match self_ty.data(interner) {
2424
TyData::Function(fn_val) => {
2525
let (binders, orig_sub) = fn_val.into_binders_and_value(interner);
26-
let all_params: Vec<_> = orig_sub.iter(interner).cloned().collect();
26+
let bound_ref = Binders::new(VariableKinds::from(interner, binders), orig_sub);
27+
builder.push_binders(&bound_ref, |builder, orig_sub| {
2728

28-
// The last parameter represents the function return type
29-
let (arg_sub, fn_output_ty) = all_params.split_at(all_params.len() - 1);
30-
let arg_sub = Substitution::from(interner, arg_sub);
31-
let fn_output_ty = fn_output_ty[0].assert_ty_ref(interner);
29+
let all_params: Vec<_> = orig_sub.iter(interner).cloned().collect();
3230

33-
// We are constructing a reference to `FnOnce<Args>`, where
34-
// `Args` is a tuple of the function's argument types
35-
let tupled = Ty::new(
36-
interner,
37-
TyData::Apply(ApplicationTy {
38-
name: TypeName::Tuple(arg_sub.len(interner)),
39-
substitution: arg_sub.clone(),
40-
}),
41-
);
31+
// The last parameter represents the function return type
32+
let (arg_sub, fn_output_ty) = all_params.split_at(all_params.len() - 1);
33+
let arg_sub = Substitution::from(interner, arg_sub);
34+
let fn_output_ty = fn_output_ty[0].assert_ty_ref(interner);
4235

43-
let tupled_sub = Substitution::from(interner, vec![self_ty.clone(), tupled]);
44-
// Given a function type `fn(A1, A2, ..., AN)`, construct a `TraitRef`
45-
// of the form `fn(A1, A2, ..., AN): FnOnce<(A1, A2, ..., AN)>`
46-
let new_trait_ref = TraitRef {
47-
trait_id,
48-
substitution: tupled_sub.clone(),
49-
};
36+
// We are constructing a reference to `FnOnce<Args>`, where
37+
// `Args` is a tuple of the function's argument types
38+
let tupled = Ty::new(
39+
interner,
40+
TyData::Apply(ApplicationTy {
41+
name: TypeName::Tuple(arg_sub.len(interner)),
42+
substitution: arg_sub.clone(),
43+
}),
44+
);
5045

51-
// Functions types come with a binder, which we push so
52-
// that the `TraitRef` properly references any bound lifetimes
53-
// (e.g. `for<'a> fn(&'a u8): FnOnce<(&'b u8)>`)
54-
let bound_ref = Binders::new(VariableKinds::from(interner, binders), new_trait_ref);
55-
builder.push_binders(&bound_ref, |this, inner_trait| {
56-
this.push_fact(inner_trait.clone());
46+
let tupled_sub = Substitution::from(interner, vec![self_ty.clone(), tupled]);
47+
// Given a function type `fn(A1, A2, ..., AN)`, construct a `TraitRef`
48+
// of the form `fn(A1, A2, ..., AN): FnOnce<(A1, A2, ..., AN)>`
49+
let new_trait_ref = TraitRef {
50+
trait_id,
51+
substitution: tupled_sub.clone(),
52+
};
53+
54+
builder.push_fact(new_trait_ref.clone());
5755

5856
if let Some(WellKnownTrait::FnOnce) = db.trait_datum(trait_id).well_known {
5957
//The `Output` type is defined on the `FnOnce`
@@ -78,7 +76,7 @@ pub fn add_fn_trait_program_clauses<I: Interner>(
7876
ty: fn_output_ty.clone(),
7977
};
8078

81-
this.push_fact(normalize);
79+
builder.push_fact(normalize);
8280
}
8381
});
8482
}

0 commit comments

Comments
 (0)