Skip to content

Commit b8a8a16

Browse files
committed
Rust: More type inference tests
1 parent c66679c commit b8a8a16

File tree

5 files changed

+648
-84
lines changed

5 files changed

+648
-84
lines changed

rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ multipleResolvedTargets
22
| main.rs:2223:9:2223:31 | ... .my_add(...) |
33
| main.rs:2225:9:2225:29 | ... .my_add(...) |
44
| main.rs:2740:13:2740:17 | x.f() |
5+
| regressions.rs:179:17:179:27 | ... + ... |

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+
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2759,6 +2759,30 @@ mod dereference;
27592759
mod dyn_type;
27602760
mod regressions;
27612761

2762+
mod arg_trait_bounds {
2763+
struct Gen<T>(T);
2764+
2765+
trait Container<T> {
2766+
fn get_input(&self) -> T;
2767+
}
2768+
2769+
fn my_get<T: Container<i64>>(c: &T) -> bool {
2770+
c.get_input() == 42 // $ target=get_input target=eq
2771+
}
2772+
2773+
impl<GT: Copy> Container<GT> for Gen<GT> {
2774+
fn get_input(&self) -> GT {
2775+
self.0 // $ fieldof=Gen
2776+
}
2777+
}
2778+
2779+
fn test() {
2780+
let v = Default::default(); // $ MISSING: type=v:i64 target=default
2781+
let g = Gen(v);
2782+
let _ = my_get(&g); // $ target=my_get
2783+
}
2784+
}
2785+
27622786
fn main() {
27632787
field_access::f(); // $ target=f
27642788
method_impl::f(); // $ target=f

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,52 @@ mod regression4 {
130130
}
131131
}
132132
}
133+
134+
mod regression5 {
135+
struct S1;
136+
struct S2<T2>(T2);
137+
138+
impl From<&S1> for S2<S1> {
139+
fn from(_: &S1) -> Self {
140+
S2(S1)
141+
}
142+
}
143+
144+
impl<T> From<T> for S2<T> {
145+
fn from(t: T) -> Self {
146+
S2(t)
147+
}
148+
}
149+
150+
fn foo() -> S2<S1> {
151+
let x = S1.into(); // $ target=into
152+
x
153+
}
154+
}
155+
156+
mod regression6 {
157+
use std::ops::Add;
158+
struct S<T>(T);
159+
160+
impl<T> Add for S<T> {
161+
type Output = Self;
162+
163+
// add1
164+
fn add(self, _rhs: Self) -> Self::Output {
165+
self
166+
}
167+
}
168+
169+
impl<T> Add<T> for S<T> {
170+
type Output = Self;
171+
172+
// add2
173+
fn add(self, _rhs: T) -> Self::Output {
174+
self
175+
}
176+
}
177+
178+
fn foo() {
179+
let x = S(0) + S(1); // $ target=add1 $ SPURIOUS: target=add2 type=x:T.T.i32
180+
}
181+
}

0 commit comments

Comments
 (0)