Skip to content

Commit f76b562

Browse files
committed
Rust: Implement type inference for 'for' loops on arrays.
1 parent 840ef5c commit f76b562

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,20 @@ private Type inferIndexExprType(IndexExpr ie, TypePath path) {
11801180
)
11811181
}
11821182

1183+
pragma[nomagic]
1184+
private Type inferForLoopExprType(AstNode n, TypePath path) {
1185+
// type of iterable -> type of pattern (loop variable)
1186+
exists(ForExpr fe, Type iterableType, TypePath iterablePath |
1187+
n = fe.getPat() and
1188+
iterableType = inferType(fe.getIterable(), iterablePath) and
1189+
(
1190+
iterablePath.isCons(any(ArrayTypeParameter tp), path) and
1191+
result = iterableType
1192+
// TODO: iterables (containers, ranges etc)
1193+
)
1194+
)
1195+
}
1196+
11831197
private module MethodCall {
11841198
/** An expression that calls a method. */
11851199
abstract private class MethodCallImpl extends Expr {
@@ -1541,6 +1555,8 @@ private module Cached {
15411555
result = inferAwaitExprType(n, path)
15421556
or
15431557
result = inferIndexExprType(n, path)
1558+
or
1559+
result = inferForLoopExprType(n, path)
15441560
}
15451561
}
15461562

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,10 +1833,10 @@ mod loops {
18331833
for u in vals2 { } // $ MISSING: type=u:u16
18341834

18351835
let vals3: [u32; 3] = [1, 2, 3]; // $ MISSING: type=vals3:[u32; 3]
1836-
for u in vals3 { } // $ MISSING: type=u:u32
1836+
for u in vals3 { } // $ type=u:u32
18371837

18381838
let vals4: [u64; 3] = [1; 3]; // $ MISSING: type=vals4:[u64; 3]
1839-
for u in vals4 { } // $ MISSING: type=u:u64
1839+
for u in vals4 { } // $ type=u:u64
18401840

18411841
let mut strings1 = ["foo", "bar", "baz"]; // $ MISSING: type=strings1:[&str; 3]
18421842
for s in &strings1 { } // $ MISSING: type=s:&str

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,6 +2641,7 @@ inferType
26412641
| main.rs:1835:32:1835:32 | 1 | | {EXTERNAL LOCATION} | i32 |
26422642
| main.rs:1835:35:1835:35 | 2 | | {EXTERNAL LOCATION} | i32 |
26432643
| main.rs:1835:38:1835:38 | 3 | | {EXTERNAL LOCATION} | i32 |
2644+
| main.rs:1836:13:1836:13 | u | | {EXTERNAL LOCATION} | u32 |
26442645
| main.rs:1836:18:1836:22 | vals3 | | file://:0:0:0:0 | [] |
26452646
| main.rs:1836:18:1836:22 | vals3 | [T;...] | {EXTERNAL LOCATION} | u32 |
26462647
| main.rs:1838:13:1838:17 | vals4 | | file://:0:0:0:0 | [] |
@@ -2650,6 +2651,7 @@ inferType
26502651
| main.rs:1838:31:1838:36 | [1; 3] | [T;...] | {EXTERNAL LOCATION} | u64 |
26512652
| main.rs:1838:32:1838:32 | 1 | | {EXTERNAL LOCATION} | i32 |
26522653
| main.rs:1838:35:1838:35 | 3 | | {EXTERNAL LOCATION} | i32 |
2654+
| main.rs:1839:13:1839:13 | u | | {EXTERNAL LOCATION} | u64 |
26532655
| main.rs:1839:18:1839:22 | vals4 | | file://:0:0:0:0 | [] |
26542656
| main.rs:1839:18:1839:22 | vals4 | [T;...] | {EXTERNAL LOCATION} | u64 |
26552657
| main.rs:1841:29:1841:33 | "foo" | | {EXTERNAL LOCATION} | str |

0 commit comments

Comments
 (0)