Skip to content

Commit 62d4e6f

Browse files
committed
Rust: Implement basic type inference in QL
1 parent 3a58611 commit 62d4e6f

24 files changed

+3196
-34
lines changed

rust/ql/.generated.list

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/.gitattributes

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,8 @@ final class RecordExprCfgNode extends Nodes::RecordExprCfgNode {
239239
pragma[nomagic]
240240
ExprCfgNode getFieldExpr(string field) {
241241
exists(RecordExprField ref |
242-
ref = node.getRecordExprFieldList().getAField() and
243-
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result) and
244-
field = ref.getFieldName()
242+
ref = node.getFieldExpr(field) and
243+
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result)
245244
)
246245
}
247246
}

rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ module Impl {
1515
private import rust
1616
private import PathResolution as PathResolution
1717

18+
pragma[nomagic]
19+
Path getFunctionPath(CallExpr ce) { result = ce.getFunction().(PathExpr).getPath() }
20+
21+
pragma[nomagic]
22+
PathResolution::ItemNode getResolvedFunction(CallExpr ce) {
23+
result = PathResolution::resolvePath(getFunctionPath(ce))
24+
}
25+
1826
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1927
/**
2028
* A function call expression. For example:
@@ -28,9 +36,15 @@ module Impl {
2836
class CallExpr extends Generated::CallExpr {
2937
override string toString() { result = this.getFunction().toAbbreviatedString() + "(...)" }
3038

39+
/** Gets the struct that this call resolves to, if any. */
40+
Struct getStruct() { result = getResolvedFunction(this) }
41+
42+
/** Gets the variant that this call resolves to, if any. */
43+
Variant getVariant() { result = getResolvedFunction(this) }
44+
3145
pragma[nomagic]
32-
private PathResolution::ItemNode getResolvedFunction(int pos) {
33-
result = PathResolution::resolvePath(this.getFunction().(PathExpr).getPath()) and
46+
private PathResolution::ItemNode getResolvedFunctionAndPos(int pos) {
47+
result = getResolvedFunction(this) and
3448
exists(this.getArgList().getArg(pos))
3549
}
3650

@@ -42,7 +56,7 @@ module Impl {
4256
*/
4357
pragma[nomagic]
4458
TupleField getTupleField(int pos) {
45-
exists(PathResolution::ItemNode i | i = this.getResolvedFunction(pos) |
59+
exists(PathResolution::ItemNode i | i = this.getResolvedFunctionAndPos(pos) |
4660
result.isStructField(i, pos) or
4761
result.isVariantField(i, pos)
4862
)

rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ private import codeql.rust.elements.internal.generated.FieldExpr
1111
* be referenced directly.
1212
*/
1313
module Impl {
14+
private import rust
15+
private import TypeInference as TypeInference
16+
1417
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1518
/**
1619
* A field access expression. For example:
@@ -19,6 +22,12 @@ module Impl {
1922
* ```
2023
*/
2124
class FieldExpr extends Generated::FieldExpr {
25+
/** Gets the record field that this access references, if any. */
26+
RecordField getRecordField() { result = TypeInference::resolveRecordFieldExpr(this) }
27+
28+
/** Gets the tuple field that this access references, if any. */
29+
TupleField getTupleField() { result = TypeInference::resolveTupleFieldExpr(this) }
30+
2231
override string toString() {
2332
exists(string abbr, string name |
2433
abbr = this.getExpr().toAbbreviatedString() and

rust/ql/lib/codeql/rust/elements/internal/GenericArgListImpl.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ private import codeql.rust.elements.internal.generated.GenericArgList
1111
* be referenced directly.
1212
*/
1313
module Impl {
14+
private import rust
15+
1416
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1517
/**
1618
* The base class for generic arguments.
@@ -22,5 +24,18 @@ module Impl {
2224
override string toString() { result = this.toAbbreviatedString() }
2325

2426
override string toAbbreviatedString() { result = "<...>" }
27+
28+
/** Gets the `i`th type argument of this list. */
29+
TypeRepr getTypeArgument(int i) {
30+
result =
31+
rank[i + 1](TypeRepr res, int j |
32+
res = this.getGenericArg(j).(TypeArg).getTypeRepr()
33+
|
34+
res order by j
35+
)
36+
}
37+
38+
/** Gets a type argument of this list. */
39+
TypeRepr getATypeArgument() { result = this.getTypeArgument(_) }
2540
}
2641
}

rust/ql/lib/codeql/rust/elements/internal/GenericParamListImpl.qll

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// generated by codegen, remove this comment if you wish to edit this file
21
/**
32
* This module provides a hand-modifiable wrapper around the generated class `GenericParamList`.
43
*
@@ -12,11 +11,26 @@ private import codeql.rust.elements.internal.generated.GenericParamList
1211
* be referenced directly.
1312
*/
1413
module Impl {
14+
private import rust
15+
16+
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1517
/**
1618
* A GenericParamList. For example:
1719
* ```rust
1820
* todo!()
1921
* ```
2022
*/
21-
class GenericParamList extends Generated::GenericParamList { }
23+
class GenericParamList extends Generated::GenericParamList {
24+
override string toString() { result = this.toAbbreviatedString() }
25+
26+
override string toAbbreviatedString() { result = "<...>" }
27+
28+
/** Gets the `i`th type parameter of this list. */
29+
TypeParam getTypeParam(int i) {
30+
result = rank[i + 1](TypeParam res, int j | res = this.getGenericParam(j) | res order by j)
31+
}
32+
33+
/** Gets a type parameter of this list. */
34+
TypeParam getATypeParam() { result = this.getTypeParam(_) }
35+
}
2236
}

0 commit comments

Comments
 (0)