Skip to content

Commit f90d53a

Browse files
authored
Merge pull request #19038 from paldepind/rust-type-inference-tweaks
Rust: Small type inference tweaks
2 parents e9ca43a + 81b28df commit f90d53a

File tree

4 files changed

+1048
-898
lines changed

4 files changed

+1048
-898
lines changed

rust/ql/lib/codeql/rust/internal/TypeInference.qll

+6-11
Original file line numberDiff line numberDiff line change
@@ -578,14 +578,9 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
578578
}
579579

580580
Declaration getTarget() {
581-
result =
582-
[
583-
CallExprImpl::getResolvedFunction(this).(AstNode),
584-
this.(CallExpr).getStruct(),
585-
this.(CallExpr).getVariant(),
586-
// mutual recursion; resolving method calls requires resolving types and vice versa
587-
resolveMethodCallExpr(this)
588-
]
581+
result = CallExprImpl::getResolvedFunction(this)
582+
or
583+
result = resolveMethodCallExpr(this) // mutual recursion; resolving method calls requires resolving types and vice versa
589584
}
590585
}
591586

@@ -908,7 +903,7 @@ private module Cached {
908903
}
909904

910905
/**
911-
* Gets a method that the method call `mce` infers to, if any.
906+
* Gets a method that the method call `mce` resolves to, if any.
912907
*/
913908
cached
914909
Function resolveMethodCallExpr(MethodCallExpr mce) {
@@ -922,7 +917,7 @@ private module Cached {
922917
}
923918

924919
/**
925-
* Gets the record field that the field expression `fe` infers to, if any.
920+
* Gets the record field that the field expression `fe` resolves to, if any.
926921
*/
927922
cached
928923
RecordField resolveRecordFieldExpr(FieldExpr fe) {
@@ -938,7 +933,7 @@ private module Cached {
938933
}
939934

940935
/**
941-
* Gets the tuple field that the field expression `fe` infers to, if any.
936+
* Gets the tuple field that the field expression `fe` resolves to, if any.
942937
*/
943938
cached
944939
TupleField resolveTupleFieldExpr(FieldExpr fe) {

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

+97-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,69 @@
1-
mod m1 {
1+
mod field_access {
2+
#[derive(Debug)]
3+
struct S;
4+
5+
#[derive(Debug)]
6+
struct MyThing {
7+
a: S,
8+
}
9+
10+
#[derive(Debug)]
11+
enum MyOption<T> {
12+
MyNone(),
13+
MySome(T),
14+
}
15+
16+
#[derive(Debug)]
17+
struct GenericThing<A> {
18+
a: A,
19+
}
20+
21+
struct OptionS {
22+
a: MyOption<S>,
23+
}
24+
25+
fn simple_field_access() {
26+
let x = MyThing { a: S };
27+
println!("{:?}", x.a);
28+
}
29+
30+
fn generic_field_access() {
31+
// Explicit type argument
32+
let x = GenericThing::<S> { a: S };
33+
println!("{:?}", x.a);
34+
35+
// Implicit type argument
36+
let y = GenericThing { a: S };
37+
println!("{:?}", x.a);
38+
39+
// The type of the field `a` can only be infered from the concrete type
40+
// in the struct declaration.
41+
let x = OptionS {
42+
a: MyOption::MyNone(),
43+
};
44+
println!("{:?}", x.a);
45+
46+
// The type of the field `a` can only be infered from the type argument
47+
let x = GenericThing::<MyOption<S>> {
48+
a: MyOption::MyNone(),
49+
};
50+
println!("{:?}", x.a);
51+
52+
let mut x = GenericThing {
53+
a: MyOption::MyNone(),
54+
};
55+
// Only after this access can we infer the type parameter of `x`
56+
let a: MyOption<S> = x.a;
57+
println!("{:?}", a);
58+
}
59+
60+
pub fn f() {
61+
simple_field_access();
62+
generic_field_access();
63+
}
64+
}
65+
66+
mod method_impl {
267
pub struct Foo {}
368

469
impl Foo {
@@ -25,7 +90,7 @@ mod m1 {
2590
}
2691
}
2792

28-
mod m2 {
93+
mod method_non_parametric_impl {
2994
#[derive(Debug)]
3095
struct MyThing<A> {
3196
a: A,
@@ -58,6 +123,10 @@ mod m2 {
58123
let x = MyThing { a: S1 };
59124
let y = MyThing { a: S2 };
60125

126+
// simple field access
127+
println!("{:?}", x.a);
128+
println!("{:?}", y.a);
129+
61130
println!("{:?}", x.m1()); // missing call target
62131
println!("{:?}", y.m1().a); // missing call target
63132

@@ -69,7 +138,7 @@ mod m2 {
69138
}
70139
}
71140

72-
mod m3 {
141+
mod method_non_parametric_trait_impl {
73142
#[derive(Debug)]
74143
struct MyThing<A> {
75144
a: A,
@@ -122,7 +191,7 @@ mod m3 {
122191
}
123192
}
124193

125-
mod m4 {
194+
mod function_trait_bounds {
126195
#[derive(Debug)]
127196
struct MyThing<A> {
128197
a: A,
@@ -175,7 +244,7 @@ mod m4 {
175244
}
176245
}
177246

178-
mod m5 {
247+
mod trait_associated_type {
179248
trait MyTrait {
180249
type AssociatedType;
181250

@@ -210,7 +279,7 @@ mod m5 {
210279
}
211280
}
212281

213-
mod m6 {
282+
mod generic_enum {
214283
#[derive(Debug)]
215284
enum MyEnum<A> {
216285
C1(A),
@@ -240,7 +309,7 @@ mod m6 {
240309
}
241310
}
242311

243-
mod m7 {
312+
mod method_supertraits {
244313
#[derive(Debug)]
245314
struct MyThing<A> {
246315
a: A,
@@ -325,7 +394,7 @@ mod m7 {
325394
}
326395
}
327396

328-
mod m8 {
397+
mod function_trait_bounds_2 {
329398
use std::convert::From;
330399
use std::fmt::Debug;
331400

@@ -374,7 +443,7 @@ mod m8 {
374443
}
375444
}
376445

377-
mod m9 {
446+
mod option_methods {
378447
#[derive(Debug)]
379448
enum MyOption<T> {
380449
MyNone(),
@@ -456,7 +525,7 @@ mod m9 {
456525
}
457526
}
458527

459-
mod m10 {
528+
mod method_call_type_conversion {
460529

461530
#[derive(Debug, Copy, Clone)]
462531
struct S<T>(T);
@@ -508,7 +577,7 @@ mod m10 {
508577
}
509578
}
510579

511-
mod m11 {
580+
mod trait_implicit_self_borrow {
512581
trait MyTrait {
513582
fn foo(&self) -> &Self;
514583

@@ -531,7 +600,7 @@ mod m11 {
531600
}
532601
}
533602

534-
mod m12 {
603+
mod implicit_self_borrow {
535604
struct S;
536605

537606
struct MyStruct<T>(T);
@@ -548,7 +617,7 @@ mod m12 {
548617
}
549618
}
550619

551-
mod m13 {
620+
mod borrowed_typed {
552621
struct S;
553622

554623
impl S {
@@ -578,18 +647,19 @@ mod m13 {
578647
}
579648

580649
fn main() {
581-
m1::f();
582-
m1::g(m1::Foo {}, m1::Foo {});
583-
m2::f();
584-
m3::f();
585-
m4::f();
586-
m5::f();
587-
m6::f();
588-
m7::f();
589-
m8::f();
590-
m9::f();
591-
m10::f();
592-
m11::f();
593-
m12::f();
594-
m13::f();
650+
field_access::f();
651+
method_impl::f();
652+
method_impl::g(method_impl::Foo {}, method_impl::Foo {});
653+
method_non_parametric_impl::f();
654+
method_non_parametric_trait_impl::f();
655+
function_trait_bounds::f();
656+
trait_associated_type::f();
657+
generic_enum::f();
658+
method_supertraits::f();
659+
function_trait_bounds_2::f();
660+
option_methods::f();
661+
method_call_type_conversion::f();
662+
trait_implicit_self_borrow::f();
663+
implicit_self_borrow::f();
664+
borrowed_typed::f();
595665
}

0 commit comments

Comments
 (0)