Skip to content

Commit 666726c

Browse files
committed
Rust: Infer types for non-overloadable operators
1 parent fafae89 commit 666726c

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import Type as T
77
private import TypeMention
88
private import codeql.typeinference.internal.TypeInference
99
private import codeql.rust.frameworks.stdlib.Stdlib
10+
private import codeql.rust.frameworks.stdlib.Bultins as Builtins
1011

1112
class Type = T::Type;
1213

@@ -190,6 +191,21 @@ private Type inferAnnotatedType(AstNode n, TypePath path) {
190191
result = getTypeAnnotation(n).resolveTypeAt(path)
191192
}
192193

194+
private Type inferLogicalOperationType(AstNode n, TypePath path) {
195+
exists(Builtins::BuiltinType t, BinaryLogicalOperation be |
196+
n = [be, be.getLhs(), be.getRhs()] and
197+
path.isEmpty() and
198+
result = TStruct(t) and
199+
t instanceof Builtins::Bool
200+
)
201+
}
202+
203+
private Type inferAssignmentOperationType(AstNode n, TypePath path) {
204+
n instanceof AssignmentOperation and
205+
path.isEmpty() and
206+
result = TUnit()
207+
}
208+
193209
/**
194210
* Holds if the type of `n1` at `path1` is the same as the type of `n2` at
195211
* `path2` and type information should propagate in both directions through the
@@ -237,6 +253,12 @@ private predicate typeEquality(AstNode n1, TypePath path1, AstNode n2, TypePath
237253
break.getTarget() = n2.(LoopExpr) and
238254
path1 = path2
239255
)
256+
or
257+
exists(AssignmentExpr be |
258+
n1 = be.getLhs() and
259+
n2 = be.getRhs() and
260+
path1 = path2
261+
)
240262
}
241263

242264
pragma[nomagic]
@@ -932,8 +954,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
932954
)
933955
}
934956

935-
private import codeql.rust.frameworks.stdlib.Bultins as Builtins
936-
937957
pragma[nomagic]
938958
private StructType inferLiteralType(LiteralExpr le) {
939959
exists(Builtins::BuiltinType t | result = TStruct(t) |
@@ -1156,6 +1176,10 @@ private module Cached {
11561176
Stages::TypeInferenceStage::ref() and
11571177
result = inferAnnotatedType(n, path)
11581178
or
1179+
result = inferLogicalOperationType(n, path)
1180+
or
1181+
result = inferAssignmentOperationType(n, path)
1182+
or
11591183
result = inferTypeEquality(n, path)
11601184
or
11611185
result = inferImplicitSelfType(n, path)

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,16 +1226,16 @@ mod builtins {
12261226

12271227
mod operators {
12281228
pub fn f() {
1229-
let x = true && false; // $ MISSING: type=x:bool
1230-
let y = true || false; // $ MISSING: type=y:bool
1229+
let x = true && false; // $ type=x:bool
1230+
let y = true || false; // $ type=y:bool
12311231

12321232
let mut a;
12331233
if 34 == 33 {
1234-
let z = (a = 1); // $ MISSING: type=z:() MISSING: type=a:i32
1234+
let z = (a = 1); // $ type=z:() type=a:i32
12351235
} else {
1236-
a = 2; // $ MISSING: type=a:i32
1236+
a = 2; // $ type=a:i32
12371237
}
1238-
a; // $ MISSING: type=a:i32
1238+
a; // $ type=a:i32
12391239
}
12401240
}
12411241

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,14 +1581,26 @@ inferType
15811581
| main.rs:1222:17:1222:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15821582
| main.rs:1223:13:1223:13 | f | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15831583
| main.rs:1223:17:1223:21 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
1584+
| main.rs:1229:13:1229:13 | x | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15841585
| main.rs:1229:17:1229:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
1586+
| main.rs:1229:17:1229:29 | ... && ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15851587
| main.rs:1229:25:1229:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
1588+
| main.rs:1230:13:1230:13 | y | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15861589
| main.rs:1230:17:1230:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
1590+
| main.rs:1230:17:1230:29 | ... \|\| ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
15871591
| main.rs:1230:25:1230:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
1592+
| main.rs:1232:13:1232:17 | mut a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
15881593
| main.rs:1233:12:1233:13 | 34 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
15891594
| main.rs:1233:18:1233:19 | 33 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
1595+
| main.rs:1234:17:1234:17 | z | | file://:0:0:0:0 | () |
1596+
| main.rs:1234:21:1234:27 | (...) | | file://:0:0:0:0 | () |
1597+
| main.rs:1234:22:1234:22 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
1598+
| main.rs:1234:22:1234:26 | ... = ... | | file://:0:0:0:0 | () |
15901599
| main.rs:1234:26:1234:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
1600+
| main.rs:1236:13:1236:13 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
1601+
| main.rs:1236:13:1236:17 | ... = ... | | file://:0:0:0:0 | () |
15911602
| main.rs:1236:17:1236:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
1603+
| main.rs:1238:9:1238:9 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
15921604
| main.rs:1244:5:1244:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo |
15931605
| main.rs:1245:5:1245:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo |
15941606
| main.rs:1245:20:1245:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo |

0 commit comments

Comments
 (0)