Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion rust/ql/.generated.list

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion rust/ql/.gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions rust/ql/consistency-queries/PathResolutionConsistency.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @name Path resolution inconsistencies
* @description Lists the path resolution inconsistencies in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/path-resolution-consistency
*/

import codeql.rust.internal.PathResolutionConsistency
8 changes: 8 additions & 0 deletions rust/ql/consistency-queries/TypeInferenceConsistency.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @name Type inference inconsistencies
* @description Lists the type inference inconsistencies in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/type-inference-consistency
*/

import codeql.rust.internal.TypeInferenceConsistency
1 change: 1 addition & 0 deletions rust/ql/integration-tests/hello-project/summary.expected
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| Files extracted - without errors % | 80 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - Path resolution | 0 |
| Inconsistencies - data flow | 0 |
| Lines of code extracted | 6 |
| Lines of user code extracted | 6 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| Files extracted - without errors % | 100 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - Path resolution | 0 |
| Inconsistencies - data flow | 0 |
| Lines of code extracted | 9 |
| Lines of user code extracted | 9 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| Files extracted - without errors % | 100 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - Path resolution | 0 |
| Inconsistencies - data flow | 0 |
| Lines of code extracted | 9 |
| Lines of user code extracted | 9 |
Expand Down
5 changes: 2 additions & 3 deletions rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,8 @@ final class RecordExprCfgNode extends Nodes::RecordExprCfgNode {
pragma[nomagic]
ExprCfgNode getFieldExpr(string field) {
exists(RecordExprField ref |
ref = node.getRecordExprFieldList().getAField() and
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result) and
field = ref.getFieldName()
ref = node.getFieldExpr(field) and
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result)
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ private import codeql.dataflow.internal.DataFlowImpl
private import rust
private import SsaImpl as SsaImpl
private import codeql.rust.controlflow.internal.Scope as Scope
private import codeql.rust.elements.internal.PathResolution
private import codeql.rust.internal.PathResolution
private import codeql.rust.controlflow.ControlFlowGraph
private import codeql.rust.controlflow.CfgNodes
private import codeql.rust.dataflow.Ssa
Expand Down Expand Up @@ -847,7 +847,7 @@ class TupleFieldContent extends FieldContent, TTupleFieldContent {

predicate isStructField(Struct s, int pos) { field.isStructField(s, pos) }

override FieldExprCfgNode getAnAccess() { none() } // TODO
override FieldExprCfgNode getAnAccess() { field = result.getFieldExpr().getTupleField() }

final override string toString() {
exists(Variant v, int pos, string vname |
Expand Down Expand Up @@ -878,7 +878,7 @@ class RecordFieldContent extends FieldContent, TRecordFieldContent {

predicate isStructField(Struct s, string name) { field.isStructField(s, name) }

override FieldExprCfgNode getAnAccess() { none() } // TODO
override FieldExprCfgNode getAnAccess() { field = result.getFieldExpr().getRecordField() }

final override string toString() {
exists(Variant v, string name, string vname |
Expand Down
17 changes: 3 additions & 14 deletions rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ private import codeql.rust.elements.Resolvable
* be referenced directly.
*/
module Impl {
private import codeql.rust.elements.internal.CallableImpl::Impl
private import codeql.rust.elements.internal.MethodCallExprImpl::Impl
private import codeql.rust.elements.internal.CallExprImpl::Impl
private import codeql.rust.elements.internal.PathExprImpl::Impl
private import codeql.rust.elements.internal.PathResolution
private import rust

pragma[nomagic]
Resolvable getCallResolvable(CallExprBase call) {
Expand All @@ -30,14 +26,7 @@ module Impl {
* A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details.
*/
class CallExprBase extends Generated::CallExprBase {
/**
* Gets the target callable of this call, if a unique such target can
* be statically resolved.
*/
Callable getStaticTarget() {
getCallResolvable(this).resolvesAsItem(result)
or
result = resolvePath(this.(CallExpr).getFunction().(PathExpr).getPath())
}
/** Gets the static target of this call, if any. */
Callable getStaticTarget() { none() } // overridden by subclasses, but cannot be made abstract
}
}
24 changes: 20 additions & 4 deletions rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ private import codeql.rust.elements.PathExpr
*/
module Impl {
private import rust
private import PathResolution as PathResolution
private import codeql.rust.internal.PathResolution as PathResolution

pragma[nomagic]
Path getFunctionPath(CallExpr ce) { result = ce.getFunction().(PathExpr).getPath() }

pragma[nomagic]
PathResolution::ItemNode getResolvedFunction(CallExpr ce) {
result = PathResolution::resolvePath(getFunctionPath(ce))
}

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
Expand All @@ -28,9 +36,17 @@ module Impl {
class CallExpr extends Generated::CallExpr {
override string toString() { result = this.getFunction().toAbbreviatedString() + "(...)" }

override Callable getStaticTarget() { result = getResolvedFunction(this) }

/** Gets the struct that this call resolves to, if any. */
Struct getStruct() { result = getResolvedFunction(this) }

/** Gets the variant that this call resolves to, if any. */
Variant getVariant() { result = getResolvedFunction(this) }

pragma[nomagic]
private PathResolution::ItemNode getResolvedFunction(int pos) {
result = PathResolution::resolvePath(this.getFunction().(PathExpr).getPath()) and
private PathResolution::ItemNode getResolvedFunctionAndPos(int pos) {
result = getResolvedFunction(this) and
exists(this.getArgList().getArg(pos))
}

Expand All @@ -42,7 +58,7 @@ module Impl {
*/
pragma[nomagic]
TupleField getTupleField(int pos) {
exists(PathResolution::ItemNode i | i = this.getResolvedFunction(pos) |
exists(PathResolution::ItemNode i | i = this.getResolvedFunctionAndPos(pos) |
result.isStructField(i, pos) or
result.isVariantField(i, pos)
)
Expand Down
9 changes: 9 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/FieldExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ private import codeql.rust.elements.internal.generated.FieldExpr
* be referenced directly.
*/
module Impl {
private import rust
private import codeql.rust.internal.TypeInference as TypeInference

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A field access expression. For example:
Expand All @@ -19,6 +22,12 @@ module Impl {
* ```
*/
class FieldExpr extends Generated::FieldExpr {
/** Gets the record field that this access references, if any. */
RecordField getRecordField() { result = TypeInference::resolveRecordFieldExpr(this) }

/** Gets the tuple field that this access references, if any. */
TupleField getTupleField() { result = TypeInference::resolveTupleFieldExpr(this) }

override string toString() {
exists(string abbr, string name |
abbr = this.getExpr().toAbbreviatedString() and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ private import codeql.rust.elements.internal.generated.GenericArgList
* be referenced directly.
*/
module Impl {
private import rust

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* The base class for generic arguments.
Expand All @@ -22,5 +24,18 @@ module Impl {
override string toString() { result = this.toAbbreviatedString() }

override string toAbbreviatedString() { result = "<...>" }

/** Gets the `i`th type argument of this list. */
TypeRepr getTypeArg(int i) {
result =
rank[i + 1](TypeRepr res, int j |
res = this.getGenericArg(j).(TypeArg).getTypeRepr()
|
res order by j
)
}

/** Gets a type argument of this list. */
TypeRepr getATypeArg() { result = this.getTypeArg(_) }
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `GenericParamList`.
*
Expand All @@ -12,11 +11,26 @@ private import codeql.rust.elements.internal.generated.GenericParamList
* be referenced directly.
*/
module Impl {
private import rust

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A GenericParamList. For example:
* ```rust
* todo!()
* ```
*/
class GenericParamList extends Generated::GenericParamList { }
class GenericParamList extends Generated::GenericParamList {
override string toString() { result = this.toAbbreviatedString() }

override string toAbbreviatedString() { result = "<...>" }

/** Gets the `i`th type parameter of this list. */
TypeParam getTypeParam(int i) {
result = rank[i + 1](TypeParam res, int j | res = this.getGenericParam(j) | res order by j)
}

/** Gets a type parameter of this list. */
TypeParam getATypeParam() { result = this.getTypeParam(_) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
* INTERNAL: Do not use.
*/

private import rust
private import codeql.rust.elements.internal.generated.MethodCallExpr
private import codeql.rust.internal.PathResolution
private import codeql.rust.internal.TypeInference

/**
* INTERNAL: This module contains the customizable definition of `MethodCallExpr` and should not
* be referenced directly.
*/
module Impl {
private predicate isImplFunction(Function f) { f = any(ImplItemNode impl).getAnAssocItem() }

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* A method call expression. For example:
Expand All @@ -20,6 +25,23 @@ module Impl {
* ```
*/
class MethodCallExpr extends Generated::MethodCallExpr {
override Function getStaticTarget() {
result = resolveMethodCallExpr(this) and
(
// prioritize `impl` methods first
isImplFunction(result)
or
not isImplFunction(resolveMethodCallExpr(this)) and
(
// then trait methods with default implementations
result.hasBody()
or
// and finally trait methods without default implementations
not resolveMethodCallExpr(this).hasBody()
)
)
}

override string toString() {
exists(string base, string separator |
base = this.getReceiver().toAbbreviatedString() and
Expand Down
20 changes: 15 additions & 5 deletions rust/ql/lib/codeql/rust/elements/internal/RecordExprImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.generated.RecordExpr
*/
module Impl {
private import rust
private import PathResolution as PathResolution
private import codeql.rust.internal.PathResolution as PathResolution

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
Expand All @@ -27,13 +27,23 @@ module Impl {
class RecordExpr extends Generated::RecordExpr {
override string toString() { result = this.getPath().toString() + " {...}" }

/** Gets the record expression for the field `name`. */
pragma[nomagic]
RecordExprField getFieldExpr(string name) {
result = this.getRecordExprFieldList().getAField() and
name = result.getFieldName()
}

pragma[nomagic]
private PathResolution::ItemNode getResolvedPath(string name) {
result = PathResolution::resolvePath(this.getPath()) and
exists(this.getFieldExpr(name))
}

/** Gets the record field that matches the `name` field of this record expression. */
pragma[nomagic]
RecordField getRecordField(string name) {
exists(PathResolution::ItemNode i |
i = PathResolution::resolvePath(this.getPath()) and
name = this.getRecordExprFieldList().getAField().getFieldName()
|
exists(PathResolution::ItemNode i | i = this.getResolvedPath(name) |
result.isStructField(i, name) or
result.isVariantField(i, name)
)
Expand Down
13 changes: 8 additions & 5 deletions rust/ql/lib/codeql/rust/elements/internal/RecordPatImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.generated.RecordPat
*/
module Impl {
private import rust
private import PathResolution as PathResolution
private import codeql.rust.internal.PathResolution as PathResolution

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
Expand All @@ -27,13 +27,16 @@ module Impl {
class RecordPat extends Generated::RecordPat {
override string toString() { result = this.getPath().toAbbreviatedString() + " {...}" }

pragma[nomagic]
private PathResolution::ItemNode getResolvedPath(string name) {
result = PathResolution::resolvePath(this.getPath()) and
name = this.getRecordPatFieldList().getAField().getFieldName()
}

/** Gets the record field that matches the `name` pattern of this pattern. */
pragma[nomagic]
RecordField getRecordField(string name) {
exists(PathResolution::ItemNode i |
i = PathResolution::resolvePath(this.getPath()) and
name = this.getRecordPatFieldList().getAField().getFieldName()
|
exists(PathResolution::ItemNode i | i = this.getResolvedPath(name) |
result.isStructField(i, name) or
result.isVariantField(i, name)
)
Expand Down
12 changes: 12 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/StructImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,17 @@ module Impl {
/** Gets the `i`th tuple field, if any. */
pragma[nomagic]
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }

/** Holds if this struct uses tuple fields. */
pragma[nomagic]
predicate isTuple() { this.getFieldList() instanceof TupleFieldList }

/**
* Holds if this struct uses record fields.
*
* Empty structs are considered to use record fields.
*/
pragma[nomagic]
predicate isRecord() { not this.isTuple() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.generated.TupleStructPat
*/
module Impl {
private import rust
private import PathResolution as PathResolution
private import codeql.rust.internal.PathResolution as PathResolution

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
Expand Down
Loading