@@ -8,11 +8,14 @@ use chalk_ir::{
88} ;
99
1010/// 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)
1314///
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
1619pub fn add_fn_trait_program_clauses < I : Interner > (
1720 db : & dyn RustIrDatabase < I > ,
1821 builder : & mut ClauseBuilder < ' _ , I > ,
@@ -25,10 +28,10 @@ pub fn add_fn_trait_program_clauses<I: Interner>(
2528 let ( binders, orig_sub) = fn_val. into_binders_and_value ( interner) ;
2629 let bound_ref = Binders :: new ( VariableKinds :: from ( interner, binders) , orig_sub) ;
2730 builder. push_binders ( & bound_ref, |builder, orig_sub| {
28- let all_params: Vec < _ > = orig_sub. iter ( interner) . cloned ( ) . collect ( ) ;
29-
3031 // 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 ) ;
3235 let arg_sub = Substitution :: from ( interner, arg_sub) ;
3336 let fn_output_ty = fn_output_ty[ 0 ] . assert_ty_ref ( interner) ;
3437
0 commit comments