@@ -8,11 +8,14 @@ use chalk_ir::{
8
8
} ;
9
9
10
10
/// Handles clauses for FnOnce/FnMut/Fn.
11
- /// If `assoc_output` is `true`, we push a clause of the form
12
- /// `Normalize(<fn(A) -> B as FnOnce<(A,)>>::Output -> B) :- Implemented(fn(A) -> B as FnOnce<(A,)>`
11
+ /// If `self_ty` is a function, we push a clause of the form
12
+ /// `fn(A1, A2, ..., AN) -> O: FnTrait<(A1, A2, ..., AN)>`, where `FnTrait`
13
+ /// is the trait corresponding to `trait_id` (FnOnce/FnMut/Fn)
13
14
///
14
- /// If `assoc_output` is `false`, we push a clause of the form
15
- /// `Implemented(fn(A) -> B as FnOnce<(A,)>)`
15
+ /// If `trait_id` is `FnOnce`, we also push a clause for the output type of the form:
16
+ /// `Normalize(<fn(A) -> B as FnOnce<(A,)>>::Output -> B)`
17
+ /// We do not add the usual `Implemented(fn(A) -> b as FnOnce<(A,)>` clause
18
+ /// as a condition, since we already called `push_fact` with it
16
19
pub fn add_fn_trait_program_clauses < I : Interner > (
17
20
db : & dyn RustIrDatabase < I > ,
18
21
builder : & mut ClauseBuilder < ' _ , I > ,
@@ -25,10 +28,10 @@ pub fn add_fn_trait_program_clauses<I: Interner>(
25
28
let ( binders, orig_sub) = fn_val. into_binders_and_value ( interner) ;
26
29
let bound_ref = Binders :: new ( VariableKinds :: from ( interner, binders) , orig_sub) ;
27
30
builder. push_binders ( & bound_ref, |builder, orig_sub| {
28
- let all_params: Vec < _ > = orig_sub. iter ( interner) . cloned ( ) . collect ( ) ;
29
-
30
31
// The last parameter represents the function return type
31
- let ( arg_sub, fn_output_ty) = all_params. split_at ( all_params. len ( ) - 1 ) ;
32
+ let ( arg_sub, fn_output_ty) = orig_sub
33
+ . parameters ( interner)
34
+ . split_at ( orig_sub. len ( interner) - 1 ) ;
32
35
let arg_sub = Substitution :: from ( interner, arg_sub) ;
33
36
let fn_output_ty = fn_output_ty[ 0 ] . assert_ty_ref ( interner) ;
34
37
0 commit comments