@@ -152,3 +152,90 @@ mod dyn_fn_once {
152152 let _r2 = apply_boxed ( Box :: new ( |_: i64 | true ) , 3 ) ; // $ target=apply_boxed target=new type=_r2:bool
153153 }
154154}
155+
156+ mod closure_infer_param {
157+ fn apply1 < F : Fn ( i64 ) -> i64 > ( f : F , a : i64 ) -> i64 {
158+ f ( a)
159+ }
160+
161+ fn apply2 ( f : impl Fn ( i64 ) -> i64 , a : i64 ) -> i64 {
162+ f ( a)
163+ }
164+
165+ fn apply3 ( f : & dyn Fn ( i64 ) -> i64 , a : i64 ) -> i64 {
166+ f ( a)
167+ }
168+
169+ fn apply4 < F : FnMut ( i64 ) -> i64 > ( mut f : F , a : i64 ) -> i64 {
170+ f ( a)
171+ }
172+
173+ fn apply5 ( f : & mut dyn FnMut ( i64 ) -> i64 , a : i64 ) -> i64 {
174+ f ( a)
175+ }
176+
177+ fn apply6 < T > ( f : impl Fn ( T ) -> i64 , a : T ) -> i64 {
178+ f ( a)
179+ }
180+
181+ fn apply7 < T , F : FnMut ( T ) -> i64 > ( mut f : F , a : T ) -> i64 {
182+ f ( a)
183+ }
184+
185+ fn test ( ) {
186+ let f = |x| x; // $ MISSING: type=x:i64
187+ let _r = apply1 ( f, 1i64 ) ; // $ target=apply1
188+
189+ let f = |x| x; // $ MISSING: type=x:i64
190+ let _r = apply2 ( f, 2i64 ) ; // $ target=apply2
191+
192+ let f = |x| x; // $ MISSING: type=x:i64
193+ let _r = apply3 ( & f, 3i64 ) ; // $ target=apply3
194+
195+ let f = |x| x; // $ MISSING: type=x:i64
196+ let _r = apply4 ( f, 4i64 ) ; // $ target=apply4
197+
198+ let mut f = |x| x; // $ MISSING: type=x:i64
199+ let _r = apply5 ( & mut f, 5i64 ) ; // $ target=apply5
200+
201+ let f = |x| x; // $ MISSING: type=x:i64
202+ let _r = apply6 ( f, 6i64 ) ; // $ target=apply6
203+
204+ let f = |x| x; // $ MISSING: type=x:i64
205+ let _r = apply7 ( f, 7i64 ) ; // $ target=apply7
206+ }
207+ }
208+
209+ mod implicit_deref {
210+ use std:: ops:: Deref ;
211+
212+ struct S < T > ( T ) ;
213+
214+ impl < T > Deref for S < T > {
215+ type Target = dyn Fn ( T ) -> bool ;
216+
217+ fn deref ( & self ) -> & Self :: Target {
218+ & |_| false
219+ }
220+ }
221+
222+ pub fn test ( ) {
223+ let x = 0i64 ;
224+ let v = Default :: default ( ) ; // $ MISSING: type=v:i64 target=default
225+ let s = S ( v) ;
226+ let _ret = s ( x) ; // $ MISSING: type=_ret:bool
227+
228+ let x = 0i32 ;
229+ let v = Default :: default ( ) ; // $ MISSING: type=v:i32 target=default
230+ let s = S ( v) ;
231+ let s_ref = & s;
232+ let _ret = s_ref ( x) ; // $ MISSING: type=_ret:bool
233+
234+ // The call below is not an implicit deref, instead it will target
235+ // `impl<A, F> FnOnce<A> for &F` from
236+ // https://doc.rust-lang.org/std/ops/trait.FnOnce.html#impl-FnOnce%3CA%3E-for-%26F
237+ // and we currently cannot handle inferring the output type
238+ let c = |x| x; // $ MISSING: type=x:i64
239+ ( & c) ( x) ; // $ MISSING: type=_:i64
240+ }
241+ }
0 commit comments