mirror of
https://github.com/github/codeql.git
synced 2026-04-23 15:55:18 +02:00
Merge pull request #19549 from paldepind/rust/type-inference-operators
Rust: Type inference for non-overloadable operators
This commit is contained in:
@@ -9,6 +9,7 @@ private import codeql.rust.elements.internal.generated.Synth
|
||||
|
||||
cached
|
||||
newtype TType =
|
||||
TUnit() or
|
||||
TStruct(Struct s) { Stages::TypeInferenceStage::ref() } or
|
||||
TEnum(Enum e) or
|
||||
TTrait(Trait t) or
|
||||
@@ -48,6 +49,21 @@ abstract class Type extends TType {
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
/** The unit type `()`. */
|
||||
class UnitType extends Type, TUnit {
|
||||
UnitType() { this = TUnit() }
|
||||
|
||||
override StructField getStructField(string name) { none() }
|
||||
|
||||
override TupleField getTupleField(int i) { none() }
|
||||
|
||||
override TypeParameter getTypeParameter(int i) { none() }
|
||||
|
||||
override string toString() { result = "()" }
|
||||
|
||||
override Location getLocation() { result instanceof EmptyLocation }
|
||||
}
|
||||
|
||||
abstract private class StructOrEnumType extends Type {
|
||||
abstract ItemNode asItemNode();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1224,6 +1224,21 @@ mod builtins {
|
||||
}
|
||||
}
|
||||
|
||||
mod operators {
|
||||
pub fn f() {
|
||||
let x = true && false; // $ type=x:bool
|
||||
let y = true || false; // $ type=y:bool
|
||||
|
||||
let mut a;
|
||||
if 34 == 33 {
|
||||
let z = (a = 1); // $ type=z:() type=a:i32
|
||||
} else {
|
||||
a = 2; // $ type=a:i32
|
||||
}
|
||||
a; // $ type=a:i32
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
field_access::f();
|
||||
method_impl::f();
|
||||
@@ -1242,4 +1257,5 @@ fn main() {
|
||||
borrowed_typed::f();
|
||||
try_expressions::f();
|
||||
builtins::f();
|
||||
operators::f();
|
||||
}
|
||||
|
||||
@@ -1581,7 +1581,27 @@ 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:5:1229:20 | ...::f(...) | | main.rs:67:5:67:21 | Foo |
|
||||
| main.rs:1230:5:1230:60 | ...::g(...) | | main.rs:67:5:67:21 | Foo |
|
||||
| main.rs:1230:20:1230:38 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo |
|
||||
| main.rs:1230:41:1230:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo |
|
||||
| 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 |
|
||||
| main.rs:1245:41:1245:59 | ...::Foo {...} | | main.rs:67:5:67:21 | Foo |
|
||||
|
||||
Reference in New Issue
Block a user