Skip to content

Commit 37c819b

Browse files
committed
Rust: More type inference tests
1 parent 2015125 commit 37c819b

File tree

2 files changed

+364
-0
lines changed

2 files changed

+364
-0
lines changed

rust/ql/test/library-tests/type-inference/closure.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)