Rust: Infer types for non-overloadable operators

This commit is contained in:
Simon Friis Vindum
2025-05-21 13:02:55 +02:00
parent fafae89502
commit 666726c935
3 changed files with 43 additions and 7 deletions

View File

@@ -7,6 +7,7 @@ private import Type as T
private import TypeMention
private import codeql.typeinference.internal.TypeInference
private import codeql.rust.frameworks.stdlib.Stdlib
private import codeql.rust.frameworks.stdlib.Bultins as Builtins
class Type = T::Type;
@@ -190,6 +191,21 @@ private Type inferAnnotatedType(AstNode n, TypePath path) {
result = getTypeAnnotation(n).resolveTypeAt(path)
}
private Type inferLogicalOperationType(AstNode n, TypePath path) {
exists(Builtins::BuiltinType t, BinaryLogicalOperation be |
n = [be, be.getLhs(), be.getRhs()] and
path.isEmpty() and
result = TStruct(t) and
t instanceof Builtins::Bool
)
}
private Type inferAssignmentOperationType(AstNode n, TypePath path) {
n instanceof AssignmentOperation and
path.isEmpty() and
result = TUnit()
}
/**
* Holds if the type of `n1` at `path1` is the same as the type of `n2` at
* `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
break.getTarget() = n2.(LoopExpr) and
path1 = path2
)
or
exists(AssignmentExpr be |
n1 = be.getLhs() and
n2 = be.getRhs() and
path1 = path2
)
}
pragma[nomagic]
@@ -932,8 +954,6 @@ private Type inferTryExprType(TryExpr te, TypePath path) {
)
}
private import codeql.rust.frameworks.stdlib.Bultins as Builtins
pragma[nomagic]
private StructType inferLiteralType(LiteralExpr le) {
exists(Builtins::BuiltinType t | result = TStruct(t) |
@@ -1156,6 +1176,10 @@ private module Cached {
Stages::TypeInferenceStage::ref() and
result = inferAnnotatedType(n, path)
or
result = inferLogicalOperationType(n, path)
or
result = inferAssignmentOperationType(n, path)
or
result = inferTypeEquality(n, path)
or
result = inferImplicitSelfType(n, path)

View File

@@ -1226,16 +1226,16 @@ mod builtins {
mod operators {
pub fn f() {
let x = true && false; // $ MISSING: type=x:bool
let y = true || false; // $ MISSING: type=y:bool
let x = true && false; // $ type=x:bool
let y = true || false; // $ type=y:bool
let mut a;
if 34 == 33 {
let z = (a = 1); // $ MISSING: type=z:() MISSING: type=a:i32
let z = (a = 1); // $ type=z:() type=a:i32
} else {
a = 2; // $ MISSING: type=a:i32
a = 2; // $ type=a:i32
}
a; // $ MISSING: type=a:i32
a; // $ type=a:i32
}
}

View File

@@ -1581,14 +1581,26 @@ inferType
| main.rs:1222:17:1222:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1223:13:1223:13 | f | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1223:17:1223:21 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1229:13:1229:13 | x | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1229:17:1229:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1229:17:1229:29 | ... && ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1229:25:1229:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1230:13:1230:13 | y | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1230:17:1230:20 | true | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1230:17:1230:29 | ... \|\| ... | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1230:25:1230:29 | false | | file:///BUILTINS/types.rs:3:1:5:16 | bool |
| main.rs:1232:13:1232:17 | mut a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1233:12:1233:13 | 34 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1233:18:1233:19 | 33 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1234:17:1234:17 | z | | file://:0:0:0:0 | () |
| main.rs:1234:21:1234:27 | (...) | | file://:0:0:0:0 | () |
| main.rs:1234:22:1234:22 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1234:22:1234:26 | ... = ... | | file://:0:0:0:0 | () |
| main.rs:1234:26:1234:26 | 1 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1236:13:1236:13 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1236:13:1236:17 | ... = ... | | file://:0:0:0:0 | () |
| main.rs:1236:17:1236:17 | 2 | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1238:9:1238:9 | a | | file:///BUILTINS/types.rs:12:1:12:15 | i32 |
| main.rs:1244:5:1244:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo |
| main.rs:1245:5:1245:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo |
| main.rs:1245:20:1245:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo |