Skip to content

Commit a90d667

Browse files
committed
Rust: Add type inference tests
1 parent ada0b37 commit a90d667

File tree

4 files changed

+465
-279
lines changed

4 files changed

+465
-279
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
multipleCallTargets
2-
| dereference.rs:61:15:61:24 | e1.deref() |
2+
| dereference.rs:69:15:69:24 | e1.deref() |
3+
| dereference.rs:186:17:186:25 | S.bar(...) |
4+
| dereference.rs:187:17:187:29 | S.bar(...) |
35
| main.rs:2308:13:2308:31 | ...::from(...) |
46
| main.rs:2309:13:2309:31 | ...::from(...) |
57
| main.rs:2310:13:2310:31 | ...::from(...) |

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

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ impl<T> Deref for MySmartPointer<T> {
2727
}
2828
}
2929

30+
struct S<T>(T);
31+
32+
impl<T> S<T> {
33+
fn foo(&self) -> &T {
34+
&self.0 // $ fieldof=S
35+
}
36+
}
37+
3038
fn explicit_monomorphic_dereference() {
3139
// Dereference with method call
3240
let a1 = MyIntPointer { value: 34i64 };
@@ -91,6 +99,9 @@ fn implicit_dereference() {
9199
// Call method on implicitly dereferenced value
92100
let x = MySmartPointer { value: 34i64 };
93101
let _y = x.is_positive(); // $ MISSING: target=is_positive type=_y:bool
102+
103+
let z = MySmartPointer { value: S(0i64) };
104+
let z_ = z.foo(); // $ MISSING: target=foo type=z_:&T.i64
94105
}
95106

96107
mod implicit_deref_coercion_cycle {
@@ -128,11 +139,90 @@ mod implicit_deref_coercion_cycle {
128139
}
129140
}
130141

142+
mod ref_vs_mut_ref {
143+
trait MyTrait1<T> {
144+
fn foo(self) -> T;
145+
}
146+
147+
struct S;
148+
149+
impl MyTrait1<S> for &S {
150+
// MyTrait1::foo1
151+
fn foo(self) -> S {
152+
S
153+
}
154+
}
155+
156+
impl MyTrait1<i64> for &mut S {
157+
// MyTrait1::foo2
158+
fn foo(self) -> i64 {
159+
42
160+
}
161+
}
162+
163+
trait MyTrait2<T1, T2> {
164+
fn bar(self, arg: T1) -> T2;
165+
}
166+
167+
impl MyTrait2<&S, S> for S {
168+
// MyTrait2::bar1
169+
fn bar(self, arg: &S) -> S {
170+
S
171+
}
172+
}
173+
174+
impl MyTrait2<&mut S, i64> for S {
175+
// MyTrait2::bar2
176+
fn bar(self, arg: &mut S) -> i64 {
177+
42
178+
}
179+
}
180+
181+
pub fn test() {
182+
let x = (&S).foo(); // $ MISSING: target=MyTrait1::foo1 type=x:S
183+
let y = S.foo(); // $ MISSING: target=MyTrait1::foo1 type=y:S
184+
let z = (&mut S).foo(); // $ MISSING: target=MyTrait1::foo2 type=z:i64
185+
186+
let x = S.bar(&S); // $ target=MyTrait2::bar1 type=x:S $ SPURIOUS: target=MyTrait2::bar2
187+
let y = S.bar(&mut S); // $ target=MyTrait2::bar2 type=y:i64 $ SPURIOUS: target=MyTrait2::bar1
188+
}
189+
}
190+
191+
// from https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-search
192+
mod rust_reference_example {
193+
struct Foo {}
194+
195+
trait Bar {
196+
fn bar(&self);
197+
}
198+
199+
impl Foo {
200+
// bar1
201+
fn bar(&mut self) {
202+
println!("In struct impl!")
203+
}
204+
}
205+
206+
impl Bar for Foo {
207+
// bar2
208+
fn bar(&self) {
209+
println!("In trait impl!")
210+
}
211+
}
212+
213+
pub fn main() {
214+
let mut f = Foo {};
215+
f.bar(); // $ SPURIOUS: target=bar1 $ MISSING: target=bar2
216+
}
217+
}
218+
131219
pub fn test() {
132220
explicit_monomorphic_dereference(); // $ target=explicit_monomorphic_dereference
133221
explicit_polymorphic_dereference(); // $ target=explicit_polymorphic_dereference
134222
explicit_ref_dereference(); // $ target=explicit_ref_dereference
135223
explicit_box_dereference(); // $ target=explicit_box_dereference
136224
implicit_dereference(); // $ target=implicit_dereference
137225
implicit_deref_coercion_cycle::test(); // $ target=test
226+
ref_vs_mut_ref::test(); // $ target=test
227+
rust_reference_example::main(); // $ target=main
138228
}

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

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -909,36 +909,36 @@ mod generic_enum {
909909
}
910910

911911
mod method_supertraits {
912-
#[derive(Debug)]
912+
#[derive(Debug, Clone, Copy)]
913913
struct MyThing<A> {
914914
a: A,
915915
}
916916

917-
#[derive(Debug)]
917+
#[derive(Debug, Clone, Copy)]
918918
struct MyThing2<A> {
919919
a: A,
920920
}
921921

922-
#[derive(Debug)]
922+
#[derive(Debug, Clone, Copy)]
923923
struct S1;
924-
#[derive(Debug)]
924+
#[derive(Debug, Clone, Copy)]
925925
struct S2;
926926

927927
trait MyTrait1<Tr1> {
928928
// MyTrait1::m1
929929
fn m1(self) -> Tr1;
930930
}
931931

932-
trait MyTrait2<Tr2>: MyTrait1<Tr2> {
932+
trait MyTrait2<Tr2>: MyTrait1<Tr2> + Copy {
933933
#[rustfmt::skip]
934-
fn m2(self) -> Tr2
934+
fn m2(&self) -> Tr2
935935
where
936936
Self: Sized,
937937
{
938938
if 3 > 2 { // $ target=gt
939939
self.m1() // $ target=MyTrait1::m1
940940
} else {
941-
Self::m1(self) // $ target=MyTrait1::m1
941+
Self::m1(*self) // $ target=deref target=MyTrait1::m1
942942
}
943943
}
944944
}
@@ -952,7 +952,7 @@ mod method_supertraits {
952952
if 3 > 2 { // $ target=gt
953953
self.m2().a // $ target=m2 $ fieldof=MyThing
954954
} else {
955-
Self::m2(self).a // $ target=m2 fieldof=MyThing
955+
Self::m2(&self).a // $ target=m2 fieldof=MyThing
956956
}
957957
}
958958
}
@@ -964,7 +964,7 @@ mod method_supertraits {
964964
}
965965
}
966966

967-
impl<T> MyTrait2<T> for MyThing<T> {}
967+
impl<T: Copy> MyTrait2<T> for MyThing<T> {}
968968

969969
impl<T> MyTrait1<MyThing<T>> for MyThing2<T> {
970970
// MyThing2::m1
@@ -973,9 +973,9 @@ mod method_supertraits {
973973
}
974974
}
975975

976-
impl<T> MyTrait2<MyThing<T>> for MyThing2<T> {}
976+
impl<T: Copy> MyTrait2<MyThing<T>> for MyThing2<T> {}
977977

978-
impl<T> MyTrait3<T> for MyThing2<T> {}
978+
impl<T: Copy> MyTrait3<T> for MyThing2<T> {}
979979

980980
fn call_trait_m1<T1, T2: MyTrait1<T1>>(x: T2) -> T1 {
981981
x.m1() // $ target=MyTrait1::m1
@@ -2558,25 +2558,23 @@ pub mod exec {
25582558
pub mod path_buf {
25592559
// a highly simplified model of `PathBuf::canonicalize`
25602560

2561-
pub struct Path {
2562-
}
2561+
pub struct Path {}
25632562

25642563
impl Path {
25652564
pub const fn new() -> Path {
2566-
Path { }
2565+
Path {}
25672566
}
25682567

25692568
pub fn canonicalize(&self) -> Result<PathBuf, ()> {
25702569
Ok(PathBuf::new()) // $ target=new
25712570
}
25722571
}
25732572

2574-
pub struct PathBuf {
2575-
}
2573+
pub struct PathBuf {}
25762574

25772575
impl PathBuf {
25782576
pub const fn new() -> PathBuf {
2579-
PathBuf { }
2577+
PathBuf {}
25802578
}
25812579
}
25822580

@@ -2587,7 +2585,7 @@ pub mod path_buf {
25872585
#[inline]
25882586
fn deref(&self) -> &Path {
25892587
// (very much not a real implementation)
2590-
static path : Path = Path::new(); // $ target=new
2588+
static path: Path = Path::new(); // $ target=new
25912589
&path
25922590
}
25932591
}

0 commit comments

Comments
 (0)