Skip to content

Commit fd5b5ba

Browse files
authored
Merge pull request #20403 from paldepind/rust/certain-struct-expr
Rust: Infer certain type information for struct expressions
2 parents ffeece1 + 671bea5 commit fd5b5ba

File tree

4 files changed

+25
-23
lines changed

4 files changed

+25
-23
lines changed

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,14 @@ module CertainTypeInference {
372372
)
373373
}
374374

375+
private Type inferCertainStructExprType(StructExpr se, TypePath path) {
376+
result = se.getPath().(TypeMention).resolveTypeAt(path)
377+
}
378+
379+
private Type inferCertainStructPatType(StructPat sp, TypePath path) {
380+
result = sp.getPath().(TypeMention).resolveTypeAt(path)
381+
}
382+
375383
predicate certainTypeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
376384
prefix1.isEmpty() and
377385
prefix2.isEmpty() and
@@ -440,6 +448,10 @@ module CertainTypeInference {
440448
or
441449
result = inferLogicalOperationType(n, path)
442450
or
451+
result = inferCertainStructExprType(n, path)
452+
or
453+
result = inferCertainStructPatType(n, path)
454+
or
443455
result = inferRangeExprType(n) and
444456
path.isEmpty()
445457
or
@@ -743,7 +755,12 @@ private module StructExprMatchingInput implements MatchingInputSig {
743755
class AccessPosition = DeclarationPosition;
744756

745757
class Access extends StructExpr {
746-
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() }
758+
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
759+
exists(TypePath suffix |
760+
suffix.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path) and
761+
result = CertainTypeInference::inferCertainType(this, suffix)
762+
)
763+
}
747764

748765
AstNode getNodeAt(AccessPosition apos) {
749766
result = this.getFieldExpr(apos.asFieldPos()).getExpr()
@@ -754,11 +771,6 @@ private module StructExprMatchingInput implements MatchingInputSig {
754771

755772
Type getInferredType(AccessPosition apos, TypePath path) {
756773
result = inferType(this.getNodeAt(apos), path)
757-
or
758-
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
759-
// `Foo<Bar>::Variant { ... }`.
760-
apos.isStructPos() and
761-
result = this.getPath().(TypeMention).resolveTypeAt(path)
762774
}
763775

764776
Declaration getTarget() { result = resolvePath(this.getPath()) }

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod field_access {
3434

3535
fn generic_field_access() {
3636
// Explicit type argument
37-
let x = GenericThing::<S> { a: S }; // $ type=x:A.S
37+
let x = GenericThing::<S> { a: S }; // $ certainType=x:A.S
3838
println!("{:?}", x.a); // $ fieldof=GenericThing
3939

4040
// Implicit type argument
@@ -2384,7 +2384,7 @@ mod loops {
23842384
let range_full = ..; // $ certainType=range_full:RangeFull
23852385
for i in &[1i64, 2i64, 3i64][range_full] {} // $ target=index MISSING: type=i:&T.i64
23862386

2387-
let range1 = // $ type=range1:Range type=range1:Idx.u16
2387+
let range1 = // $ certainType=range1:Range type=range1:Idx.u16
23882388
std::ops::Range {
23892389
start: 0u16,
23902390
end: 10u16,
@@ -2480,7 +2480,7 @@ mod explicit_type_args {
24802480
let x7 = S4(S2); // $ type=x7:T4.S2
24812481
let x8 = S4(0); // $ type=x8:T4.i32
24822482
let x9 = S4(S2::default()); // $ type=x9:T4.S2 target=default
2483-
let x10 = S5::<S2> // $ type=x10:T5.S2
2483+
let x10 = S5::<S2> // $ certainType=x10:T5.S2
24842484
{
24852485
field: Default::default(), // $ target=default
24862486
};
@@ -2594,7 +2594,7 @@ pub mod exec {
25942594
impl Connection for MySqlConnection {}
25952595

25962596
pub fn f() {
2597-
let c = MySqlConnection {}; // $ type=c:MySqlConnection
2597+
let c = MySqlConnection {}; // $ certainType=c:MySqlConnection
25982598

25992599
c.execute1(); // $ MISSING: target=execute1
26002600
MySqlConnection::execute1(&c); // $ MISSING: target=execute1

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,16 @@ pub fn record_patterns() {
360360
// RecordPat - Record (struct) patterns
361361
match point {
362362
Point { x: 0, y: 0 } => {
363-
let origin = point; // $ type=origin:Point
363+
let origin = point; // $ certainType=origin:Point
364364
println!("Origin point: {:?}", origin);
365365
}
366366
Point { x, y: 0 } => {
367367
let x_axis_x = x; // $ type=x_axis_x:i32
368-
let x_axis_point = point; // $ type=x_axis_point:Point
368+
let x_axis_point = point; // $ certainType=x_axis_point:Point
369369
println!("Point on x-axis: x={}, point={:?}", x_axis_x, x_axis_point);
370370
}
371371
Point { x: 10, .. } => {
372-
let ten_x_point = point; // $ type=ten_x_point:Point
372+
let ten_x_point = point; // $ certainType=ten_x_point:Point
373373
println!("Point with x=10: {:?}", ten_x_point);
374374
}
375375
Point { x, y } => {

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,6 @@ inferType
385385
| dereference.rs:122:23:122:29 | &... | &T | file://:0:0:0:0 | & |
386386
| dereference.rs:122:23:122:29 | &... | &T.&T | dereference.rs:99:5:100:21 | Key |
387387
| dereference.rs:122:24:122:29 | Key {...} | | dereference.rs:99:5:100:21 | Key |
388-
| dereference.rs:122:24:122:29 | Key {...} | | file://:0:0:0:0 | & |
389-
| dereference.rs:122:24:122:29 | Key {...} | &T | dereference.rs:99:5:100:21 | Key |
390388
| dereference.rs:123:16:123:28 | Some(...) | | {EXTERNAL LOCATION} | Option |
391389
| dereference.rs:123:16:123:28 | Some(...) | T | file://:0:0:0:0 | & |
392390
| dereference.rs:123:16:123:28 | Some(...) | T.&T | dereference.rs:99:5:100:21 | Key |
@@ -501,10 +499,8 @@ inferType
501499
| dyn_type.rs:61:5:61:36 | ...::new(...) | T | dyn_type.rs:33:1:36:1 | GenStruct |
502500
| dyn_type.rs:61:5:61:36 | ...::new(...) | T.A | dyn_type.rs:60:18:60:43 | A |
503501
| dyn_type.rs:61:5:61:36 | ...::new(...) | T.dyn(A) | dyn_type.rs:60:18:60:43 | A |
504-
| dyn_type.rs:61:14:61:35 | GenStruct {...} | | dyn_type.rs:10:1:13:1 | dyn GenericGet |
505502
| dyn_type.rs:61:14:61:35 | GenStruct {...} | | dyn_type.rs:33:1:36:1 | GenStruct |
506503
| dyn_type.rs:61:14:61:35 | GenStruct {...} | A | dyn_type.rs:60:18:60:43 | A |
507-
| dyn_type.rs:61:14:61:35 | GenStruct {...} | dyn(A) | dyn_type.rs:60:18:60:43 | A |
508504
| dyn_type.rs:61:33:61:33 | a | | dyn_type.rs:60:18:60:43 | A |
509505
| dyn_type.rs:64:25:64:27 | obj | | file://:0:0:0:0 | & |
510506
| dyn_type.rs:64:25:64:27 | obj | &T | dyn_type.rs:5:1:8:1 | dyn MyTrait1 |
@@ -623,16 +619,13 @@ inferType
623619
| dyn_type.rs:102:26:102:48 | &... | | file://:0:0:0:0 | & |
624620
| dyn_type.rs:102:26:102:48 | &... | &T | dyn_type.rs:5:1:8:1 | dyn MyTrait1 |
625621
| dyn_type.rs:102:26:102:48 | &... | &T | dyn_type.rs:21:1:24:1 | MyStruct |
626-
| dyn_type.rs:102:27:102:48 | MyStruct {...} | | dyn_type.rs:5:1:8:1 | dyn MyTrait1 |
627622
| dyn_type.rs:102:27:102:48 | MyStruct {...} | | dyn_type.rs:21:1:24:1 | MyStruct |
628623
| dyn_type.rs:102:45:102:46 | 42 | | {EXTERNAL LOCATION} | i32 |
629624
| dyn_type.rs:103:28:105:5 | &... | | file://:0:0:0:0 | & |
630625
| dyn_type.rs:103:28:105:5 | &... | &T | dyn_type.rs:10:1:13:1 | dyn GenericGet |
631626
| dyn_type.rs:103:28:105:5 | &... | &T | dyn_type.rs:33:1:36:1 | GenStruct |
632627
| dyn_type.rs:103:28:105:5 | &... | &T.dyn(A) | {EXTERNAL LOCATION} | String |
633-
| dyn_type.rs:103:29:105:5 | GenStruct {...} | | dyn_type.rs:10:1:13:1 | dyn GenericGet |
634628
| dyn_type.rs:103:29:105:5 | GenStruct {...} | | dyn_type.rs:33:1:36:1 | GenStruct |
635-
| dyn_type.rs:103:29:105:5 | GenStruct {...} | dyn(A) | {EXTERNAL LOCATION} | String |
636629
| dyn_type.rs:104:16:104:17 | "" | | file://:0:0:0:0 | & |
637630
| dyn_type.rs:104:16:104:17 | "" | &T | {EXTERNAL LOCATION} | str |
638631
| dyn_type.rs:107:21:107:45 | &... | | file://:0:0:0:0 | & |
@@ -641,11 +634,8 @@ inferType
641634
| dyn_type.rs:107:21:107:45 | &... | &T.A | {EXTERNAL LOCATION} | i32 |
642635
| dyn_type.rs:107:21:107:45 | &... | &T.dyn(AP) | {EXTERNAL LOCATION} | bool |
643636
| dyn_type.rs:107:21:107:45 | &... | &T.dyn(GP) | {EXTERNAL LOCATION} | i64 |
644-
| dyn_type.rs:107:22:107:45 | GenStruct {...} | | dyn_type.rs:15:1:19:1 | dyn AssocTrait |
645637
| dyn_type.rs:107:22:107:45 | GenStruct {...} | | dyn_type.rs:33:1:36:1 | GenStruct |
646638
| dyn_type.rs:107:22:107:45 | GenStruct {...} | A | {EXTERNAL LOCATION} | i32 |
647-
| dyn_type.rs:107:22:107:45 | GenStruct {...} | dyn(AP) | {EXTERNAL LOCATION} | bool |
648-
| dyn_type.rs:107:22:107:45 | GenStruct {...} | dyn(GP) | {EXTERNAL LOCATION} | i64 |
649639
| dyn_type.rs:107:41:107:43 | 100 | | {EXTERNAL LOCATION} | i32 |
650640
| loop/main.rs:7:12:7:15 | SelfParam | | loop/main.rs:6:1:8:1 | Self [trait T1] |
651641
| loop/main.rs:11:12:11:15 | SelfParam | | loop/main.rs:10:1:14:1 | Self [trait T2] |

0 commit comments

Comments
 (0)