Merge branch 'main' into rust-data-flow-split

This commit is contained in:
Simon Friis Vindum
2025-03-14 09:58:46 +01:00
105 changed files with 4694 additions and 354 deletions

View File

@@ -286,7 +286,6 @@ lib/codeql/rust/elements/internal/GenericArgImpl.qll 6b1b804c357425c223f926e560a
lib/codeql/rust/elements/internal/GenericArgListConstructor.qll 46859bb3eb09d77987a18642d65ba2e13471a4dc9c0a83a192fddc82e37c335c 2c7d54c876269a88d3461b05745e73b06532b1616cae9b614ac94b28735d8fc4
lib/codeql/rust/elements/internal/GenericParamImpl.qll f435f80d7f275803c1311d362467f4a367deb5a2c0245b17a9e12468a2c3ce2f 8e8fcc29f510efa03ce194ad3a1e2ae3fbd7f8e04ab5a4a2d1db03e95f388446
lib/codeql/rust/elements/internal/GenericParamListConstructor.qll 7221146d1724e0add3a8e70e0e46670142589eb7143425e1871ac4358a8c8bdb 2fbb7576444d6b2da6164245e2660d592d276ae2c1ca9f2bda5656b1c5c0a73a
lib/codeql/rust/elements/internal/GenericParamListImpl.qll 524aa0949df6d4d2cb9bee6226650f63a6f181d7644933fa265673b281074885 27b0210e5eaa2040bc8a093e35e1394befb6994b25369544738d0447ef269a9c
lib/codeql/rust/elements/internal/IdentPatConstructor.qll 09792f5a070996b65f095dc6b1b9e0fb096a56648eed26c0643c59f82377cab0 0bb1a9fcdc62b5197aef3dd6e0ea4d679dde10d5be54b57b5209727ba66e078b
lib/codeql/rust/elements/internal/IfExprConstructor.qll 03088b54c8fa623f93a5b5a7eb896f680e8b0e9025488157a02c48aaebc6ad56 906f916c3690d0721a31dd31b302dcdcec4233bb507683007d82cf10793a648f
lib/codeql/rust/elements/internal/ImplConstructor.qll 24edccca59f70d812d1458b412a45310ddc096d095332f6e3258903c54c1bb44 7eb673b3ab33a0873ee5ce189105425066b376821cce0fc9eb8ace22995f0bc7
@@ -577,7 +576,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
lib/codeql/rust/elements/internal/generated/ParenPat.qll 4f168ef5d5bb87a903251cc31b2e44a759b099ec69c90af31783fbb15778c940 0e34f94a45a13396fd57d94c245dc64d1adde2ab0e22b56946f7e94c04e297fc
lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 40ab5c592e7699c621787793743e33988de71ff42ca27599f5ab3ddb70e3f7d8 12c0a6eed2202ee3e892f61da3b3ce77ac3190854cdf3097e8d2be98aa3cb91d
lib/codeql/rust/elements/internal/generated/ParentChild.qll 9858c29b5852292e87dedc9bc9105b17915f5eb8198b6a29a2d621e26b7440ef 17c1a3e7bb344c7f9584ee2f28de622eb0f17ca4d967231f6215aa36261eeec9
lib/codeql/rust/elements/internal/generated/ParentChild.qll eec4e7672ef5f07752044348d45882f0a849b295dfb17169e910ed0bfca3c162 29a9cc9b2870b1c6240cc53a9a70c4623381219a8f88ea1656b6828d16ef51c7
lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll c5fa328ea60d3a3333d7c7bb3480969c1873166c7ac8ebb9d0afad7a8099d1a8 2dbbb6200d96f7db7dea4a55bdeab8d67b14d39a43e0bd54ada019f7e466f163
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
lib/codeql/rust/elements/internal/generated/Path.qll 8e47e91aff3f8c60f1ee8cb3887b8e4936c38e4665d052f2c92a939a969aac29 2c28beb89cabd7c7c91a5bc65c874f414cb96bbefde37b25811b61089a8a0053

1
rust/ql/.gitattributes generated vendored
View File

@@ -288,7 +288,6 @@
/lib/codeql/rust/elements/internal/GenericArgListConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/GenericParamImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/GenericParamListConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/GenericParamListImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/IdentPatConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/IfExprConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ImplConstructor.qll linguist-generated

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -152,6 +152,29 @@ class ModeledRemoteSource extends RemoteSource::Range {
ModeledRemoteSource() { sourceNode(this, "remote") }
}
/**
* A data flow sink that is used in a query.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `QuerySink::Range` instead.
*/
final class QuerySink = QuerySink::Range;
/**
* Provides a class for modeling new query sinks.
*/
module QuerySink {
/**
* A data flow sink that is used in a query.
*/
abstract class Range extends DataFlow::Node {
/**
* Gets a string that describes the type of this sink (usually the query it applies to).
*/
abstract string getSinkType();
}
}
/**
* A data flow node that constructs a SQL statement (for later execution).
*

View File

@@ -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)
)
}
}

View File

@@ -1,4 +1,22 @@
/** Provides classes and predicates for defining flow sinks. */
/**
* Provides classes and predicates for defining flow sinks.
*
* Flow sinks defined here feed into data flow configurations as follows:
*
* ```text
* data from *.model.yml | QL extensions of FlowSink::Range
* v v
* FlowSink (associated with a models-as-data kind string)
* v
* sinkNode predicate | other QL defined sinks, for example using concepts
* v v
* various Sink classes for specific data flow configurations <- extending QuerySink
* ```
*
* New sinks should be defined using models-as-data, QL extensions of
* `FlowSink::Range`, or concepts. Data flow configurations should use the
* `sinkNode` predicate and/or concepts to define their sinks.
*/
private import rust
private import internal.FlowSummaryImpl as Impl
@@ -12,7 +30,7 @@ private module Sinks {
/** Provides the `Range` class used to define the extent of `FlowSink`. */
module FlowSink {
/** A flow source. */
/** A flow sink. */
abstract class Range extends Impl::Public::SinkElement {
bindingset[this]
Range() { any() }

View File

@@ -1,4 +1,28 @@
/** Provides classes and predicates for defining flow sources. */
/**
* Provides classes and predicates for defining flow sources.
*
* Flow sources defined here feed into the `ActiveThreatModelSource` class and
* ultimately reach data flow configurations as follows:
*
* ```text
* data from *.model.yml | QL extensions of FlowSource::Range
* v v
* FlowSource (associated with a models-as-data kind string)
* v
* sourceNode predicate | (theoretically other QL defined sources)
* v v
* ThreatModelSource (associated with a threat model source type)
* v
* ActiveThreatModelSource (just the enabled sources)
* v
* various Source classes for specific data flow configurations
* ```
*
* New sources should be defined using models-as-data or QL extensions of
* `FlowSource::Range`. Data flow configurations on the other hand should use
* `ActiveThreatModelSource` to match sources enabled in the user
* configuration.
*/
private import rust
private import internal.FlowSummaryImpl as Impl

View File

@@ -34,7 +34,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 |
@@ -65,7 +65,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 |

View File

@@ -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

View File

@@ -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) {
@@ -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
}
}

View File

@@ -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
/**
@@ -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))
}
@@ -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)
)

View File

@@ -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:
@@ -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

View File

@@ -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.
@@ -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(_) }
}
}

View File

@@ -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`.
*
@@ -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(_) }
}
}

View File

@@ -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:
@@ -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

View File

@@ -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
/**
@@ -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)
)

View File

@@ -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
/**
@@ -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)
)

View File

@@ -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() }
}
}

View File

@@ -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
/**

View File

@@ -11,6 +11,8 @@ private import codeql.rust.elements.internal.generated.TypeParam
* 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 TypeParam. For example:
@@ -19,6 +21,9 @@ module Impl {
* ```
*/
class TypeParam extends Generated::TypeParam {
/** Gets the position of this type parameter. */
int getPosition() { this = any(GenericParamList l).getTypeParam(result) }
override string toAbbreviatedString() { result = this.getName().getText() }
override string toString() { result = this.getName().getText() }

View File

@@ -236,13 +236,11 @@ module Impl {
this instanceof VariableScope or
this instanceof VariableAccessCand or
this instanceof LetStmt or
getImmediateChildAndAccessor(this, _, _) instanceof RelevantElement
getImmediateChild(this, _) instanceof RelevantElement
}
pragma[nomagic]
private RelevantElement getChild(int index) {
result = getImmediateChildAndAccessor(this, index, _)
}
private RelevantElement getChild(int index) { result = getImmediateChild(this, index) }
pragma[nomagic]
private RelevantElement getImmediateChildMin(int index) {

View File

@@ -32,5 +32,20 @@ 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 variant uses tuple fields. */
pragma[nomagic]
predicate isTuple() { this.getFieldList() instanceof TupleFieldList }
/**
* Holds if this variant uses record fields.
*
* Empty variants are considered to use record fields.
*/
pragma[nomagic]
predicate isRecord() { not this.isTuple() }
/** Gets the enum that this variant belongs to. */
Enum getEnum() { this = result.getVariantList().getAVariant() }
}
}

View File

@@ -4403,6 +4403,11 @@ Element getImmediateParent(Element e) {
result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x)
}
/**
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct.
*/
Element getImmediateChild(Element e, int index) { result = Impl::getImmediateChild(e, index, _) }
/**
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
*/
@@ -4422,3 +4427,8 @@ Element getChildAndAccessor(Element e, int index, string accessor) {
accessor = "get" + partialAccessor
)
}
/**
* Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
*/
Element getChild(Element e, int index) { result = Impl::getImmediateChild(e, index, _).resolve() }

View File

@@ -1,5 +1,5 @@
/**
* Provides classes for recognizing control flow graph inconsistencies.
* Provides classes for recognizing AST inconsistencies.
*/
private import rust
@@ -40,7 +40,7 @@ query predicate multiplePrimaryQlClasses(Element e, string s) {
s = strictconcat(e.getPrimaryQlClasses(), ", ")
}
private Element getParent(Element child) { child = getChildAndAccessor(result, _, _) }
private Element getParent(Element child) { child = getChild(result, _) }
private predicate multipleParents(Element child) { strictcount(getParent(child)) > 1 }
@@ -56,8 +56,8 @@ query predicate multipleParents(Element child, string childClass, Element parent
/** Holds if `parent` has multiple children at the same index. */
query predicate multipleChildren(Element parent, int index, Element child1, Element child2) {
child1 = getChildAndAccessor(parent, index, _) and
child2 = getChildAndAccessor(parent, index, _) and
child1 = getChild(parent, index) and
child2 = getChild(parent, index) and
child1 != child2
}
@@ -75,20 +75,6 @@ query predicate multiplePositions(Element parent, int pos1, int pos2, string acc
pos1 != pos2
}
private import codeql.rust.elements.internal.PathResolution
/** Holds if `p` may resolve to multiple items including `i`. */
query predicate multiplePathResolutions(Path p, ItemNode i) {
i = resolvePath(p) and
// `use foo::bar` may use both a type `bar` and a value `bar`
not p =
any(UseTree use |
not use.isGlob() and
not use.hasUseTreeList()
).getPath() and
strictcount(resolvePath(p)) > 1
}
/**
* Gets counts of abstract syntax tree inconsistencies of each type.
*/
@@ -114,7 +100,4 @@ int getAstInconsistencyCounts(string type) {
or
type = "Multiple positions" and
result = count(Element e | multiplePositions(_, _, _, _, e) | e)
or
type = "Multiple path resolutions" and
result = count(Path p | multiplePathResolutions(p, _) | p)
}

View File

@@ -95,6 +95,36 @@ module Stages {
}
}
/**
* The type inference stage.
*/
cached
module TypeInference {
private import codeql.rust.internal.Type
private import codeql.rust.internal.TypeInference
/**
* Always holds.
* Ensures that a predicate is evaluated as part of the CFG stage.
*/
cached
predicate ref() { 1 = 1 }
/**
* DO NOT USE!
*
* Contains references to each predicate that use the above `ref` predicate.
*/
cached
predicate backref() {
1 = 1
or
exists(Type t)
or
exists(inferType(_))
}
}
/**
* The data flow stage.
*/

View File

@@ -83,6 +83,9 @@ abstract class ItemNode extends AstNode {
/** Gets the visibility of this item, if any. */
abstract Visibility getVisibility();
/** Gets the `i`th type parameter of this item, if any. */
abstract TypeParam getTypeParam(int i);
/** Holds if this item is declared as `pub`. */
bindingset[this]
pragma[inline_late]
@@ -207,6 +210,8 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
}
override Visibility getVisibility() { none() }
override TypeParam getTypeParam(int i) { none() }
}
/** An item that can occur in a trait or an `impl` block. */
@@ -223,6 +228,8 @@ private class ConstItemNode extends AssocItemNode instanceof Const {
override Namespace getNamespace() { result.isValue() }
override Visibility getVisibility() { result = Const.super.getVisibility() }
override TypeParam getTypeParam(int i) { none() }
}
private class EnumItemNode extends ItemNode instanceof Enum {
@@ -231,6 +238,8 @@ private class EnumItemNode extends ItemNode instanceof Enum {
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { result = Enum.super.getVisibility() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
}
private class VariantItemNode extends ItemNode instanceof Variant {
@@ -240,6 +249,10 @@ private class VariantItemNode extends ItemNode instanceof Variant {
if super.getFieldList() instanceof RecordFieldList then result.isType() else result.isValue()
}
override TypeParam getTypeParam(int i) {
result = super.getEnum().getGenericParamList().getTypeParam(i)
}
override Visibility getVisibility() { result = Variant.super.getVisibility() }
}
@@ -250,10 +263,12 @@ class FunctionItemNode extends AssocItemNode instanceof Function {
override Namespace getNamespace() { result.isValue() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
override Visibility getVisibility() { result = Function.super.getVisibility() }
}
abstract private class ImplOrTraitItemNode extends ItemNode {
abstract class ImplOrTraitItemNode extends ItemNode {
/** Gets an item that may refer to this node using `Self`. */
pragma[nomagic]
ItemNode getAnItemInSelfScope() {
@@ -265,6 +280,24 @@ abstract private class ImplOrTraitItemNode extends ItemNode {
not mid instanceof ImplOrTraitItemNode
)
}
/** Gets a `Self` path that refers to this item. */
Path getASelfPath() {
isUnqualifiedSelfPath(result) and
this = unqualifiedPathLookup(result, _)
}
/** Gets an associated item belonging to this trait or `impl` block. */
abstract AssocItemNode getAnAssocItem();
/** Holds if this trait or `impl` block declares an associated item named `name`. */
pragma[nomagic]
predicate hasAssocItem(string name) { name = this.getAnAssocItem().getName() }
}
pragma[nomagic]
private TypeParamItemNode resolveTypeParamPathTypeRepr(PathTypeRepr ptr) {
result = resolvePath(ptr.getPath())
}
class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
@@ -276,18 +309,71 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
/** Holds if this `impl` block declares an associated item named `name`. */
pragma[nomagic]
predicate hasAssocItem(string name) {
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
private TypeRepr getASelfTyArg() {
result =
this.getSelfPath().getPart().getGenericArgList().getAGenericArg().(TypeArg).getTypeRepr()
}
/**
* Holds if this `impl` block is not fully parametric. That is, the implementing
* type is generic and the implementation is not parametrically polymorphic in all
* the implementing type's arguments.
*
* Examples:
*
* ```rust
* impl Foo { ... } // fully parametric
*
* impl<T> Foo<T> { ... } // fully parametric
*
* impl Foo<i64> { ... } // not fully parametric
*
* impl<T> Foo<Foo<T>> { ... } // not fully parametric
*
* impl<T: Trait> Foo<T> { ... } // not fully parametric
*
* impl<T> Foo<T> where T: Trait { ... } // not fully parametric
* ```
*/
pragma[nomagic]
predicate isNotFullyParametric() {
exists(TypeRepr arg | arg = this.getASelfTyArg() |
not exists(resolveTypeParamPathTypeRepr(arg))
or
resolveTypeParamPathTypeRepr(arg).hasTraitBound()
)
}
/**
* Holds if this `impl` block is fully parametric. Examples:
*
* ```rust
* impl Foo { ... } // fully parametric
*
* impl<T> Foo<T> { ... } // fully parametric
*
* impl Foo<i64> { ... } // not fully parametric
*
* impl<T> Foo<Foo<T>> { ... } // not fully parametric
*
* impl<T: Trait> Foo<T> { ... } // not fully parametric
*
* impl<T> Foo<T> where T: Trait { ... } // not fully parametric
* ```
*/
predicate isFullyParametric() { not this.isNotFullyParametric() }
override AssocItemNode getAnAssocItem() { result = super.getAssocItemList().getAnAssocItem() }
override string getName() { result = "(impl)" }
override Namespace getNamespace() {
result.isType() // can be referenced with `Self`
}
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
override Visibility getVisibility() { result = Impl.super.getVisibility() }
}
@@ -298,6 +384,8 @@ private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
override Namespace getNamespace() { none() }
override TypeParam getTypeParam(int i) { none() }
override Visibility getVisibility() { none() }
}
@@ -307,6 +395,8 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { result = Module.super.getVisibility() }
override TypeParam getTypeParam(int i) { none() }
}
private class StructItemNode extends ItemNode instanceof Struct {
@@ -320,6 +410,8 @@ private class StructItemNode extends ItemNode instanceof Struct {
}
override Visibility getVisibility() { result = Struct.super.getVisibility() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
}
class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
@@ -330,17 +422,15 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
/** Holds if this trait declares an associated item named `name`. */
pragma[nomagic]
predicate hasAssocItem(string name) {
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
}
override AssocItemNode getAnAssocItem() { result = super.getAssocItemList().getAnAssocItem() }
override string getName() { result = Trait.super.getName().getText() }
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { result = Trait.super.getVisibility() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
}
class TypeAliasItemNode extends AssocItemNode instanceof TypeAlias {
@@ -351,6 +441,8 @@ class TypeAliasItemNode extends AssocItemNode instanceof TypeAlias {
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { result = TypeAlias.super.getVisibility() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
}
private class UnionItemNode extends ItemNode instanceof Union {
@@ -359,6 +451,8 @@ private class UnionItemNode extends ItemNode instanceof Union {
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { result = Union.super.getVisibility() }
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }
}
private class UseItemNode extends ItemNode instanceof Use {
@@ -367,6 +461,8 @@ private class UseItemNode extends ItemNode instanceof Use {
override Namespace getNamespace() { none() }
override Visibility getVisibility() { none() }
override TypeParam getTypeParam(int i) { none() }
}
private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
@@ -375,6 +471,8 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
override Namespace getNamespace() { none() }
override Visibility getVisibility() { none() }
override TypeParam getTypeParam(int i) { none() }
}
private class TypeParamItemNode extends ItemNode instanceof TypeParam {
@@ -385,12 +483,50 @@ private class TypeParamItemNode extends ItemNode instanceof TypeParam {
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
/**
* Holds if this type parameter has a trait bound. Examples:
*
* ```rust
* impl<T> Foo<T> { ... } // has no trait bound
*
* impl<T: Trait> Foo<T> { ... } // has trait bound
*
* impl<T> Foo<T> where T: Trait { ... } // has trait bound
* ```
*/
pragma[nomagic]
predicate hasTraitBound() {
exists(this.getABoundPath())
or
exists(ItemNode declaringItem, WherePred wp |
this = resolveTypeParamPathTypeRepr(wp.getTypeRepr()) and
wp = declaringItem.getADescendant() and
this = declaringItem.getADescendant()
)
}
/**
* Holds if this type parameter has no trait bound. Examples:
*
* ```rust
* impl<T> Foo<T> { ... } // has no trait bound
*
* impl<T: Trait> Foo<T> { ... } // has trait bound
*
* impl<T> Foo<T> where T: Trait { ... } // has trait bound
* ```
*/
pragma[nomagic]
predicate hasNoTraitBound() { not this.hasTraitBound() }
override string getName() { result = TypeParam.super.getName().getText() }
override Namespace getNamespace() { result.isType() }
override Visibility getVisibility() { none() }
override TypeParam getTypeParam(int i) { none() }
override Location getLocation() { result = TypeParam.super.getName().getLocation() }
}
@@ -547,14 +683,23 @@ private ItemNode getASuccessor(ItemNode pred, string name, Namespace ns) {
}
pragma[nomagic]
private ItemNode resolvePath0(RelevantPath path) {
exists(ItemNode encl, Namespace ns, string name, ItemNode res |
private ItemNode unqualifiedPathLookup(RelevantPath path, Namespace ns) {
exists(ItemNode encl, string name |
unqualifiedPathLookup(path, name, ns, encl) and
res = getASuccessor(encl, name, ns)
|
result = getASuccessor(encl, name, ns)
)
}
pragma[nomagic]
private predicate isUnqualifiedSelfPath(RelevantPath path) { path.isUnqualified("Self") }
pragma[nomagic]
private ItemNode resolvePath0(RelevantPath path, Namespace ns) {
exists(ItemNode res |
res = unqualifiedPathLookup(path, ns) and
if
not any(RelevantPath parent).getQualifier() = path and
name = "Self" and
isUnqualifiedSelfPath(path) and
res instanceof ImplItemNode
then result = res.(ImplItemNode).resolveSelfTy()
else result = res
@@ -562,10 +707,12 @@ private ItemNode resolvePath0(RelevantPath path) {
or
exists(ItemNode q, string name |
q = resolvePathQualifier(path, name) and
result = q.getASuccessor(name)
result = q.getASuccessor(name) and
ns = result.getNamespace()
)
or
result = resolveUseTreeListItem(_, _, path)
result = resolveUseTreeListItem(_, _, path) and
ns = result.getNamespace()
}
/** Holds if path `p` must be looked up in namespace `n`. */
@@ -601,9 +748,8 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
/** Gets the item that `path` resolves to, if any. */
cached
ItemNode resolvePath(RelevantPath path) {
result = resolvePath0(path) and
(
pathUsesNamespace(path, result.getNamespace())
exists(Namespace ns | result = resolvePath0(path, ns) |
pathUsesNamespace(path, ns)
or
not pathUsesNamespace(path, _)
)

View File

@@ -0,0 +1,53 @@
/**
* Provides classes for recognizing path resolution inconsistencies.
*/
private import rust
private import PathResolution
/** Holds if `p` may resolve to multiple items including `i`. */
query predicate multiplePathResolutions(Path p, ItemNode i) {
i = resolvePath(p) and
// `use foo::bar` may use both a type `bar` and a value `bar`
not p =
any(UseTree use |
not use.isGlob() and
not use.hasUseTreeList()
).getPath() and
strictcount(resolvePath(p)) > 1
}
/** Holds if `call` has multiple static call targets including `target`. */
query predicate multipleStaticCallTargets(CallExprBase call, Callable target) {
target = call.getStaticTarget() and
strictcount(call.getStaticTarget()) > 1
}
/** Holds if `fe` resolves to multiple record fields including `field`. */
query predicate multipleRecordFields(FieldExpr fe, RecordField field) {
field = fe.getRecordField() and
strictcount(fe.getRecordField()) > 1
}
/** Holds if `fe` resolves to multiple tuple fields including `field`. */
query predicate multipleTupleFields(FieldExpr fe, TupleField field) {
field = fe.getTupleField() and
strictcount(fe.getTupleField()) > 1
}
/**
* Gets counts of path resolution inconsistencies of each type.
*/
int getPathResolutionInconsistencyCounts(string type) {
type = "Multiple path resolutions" and
result = count(Path p | multiplePathResolutions(p, _) | p)
or
type = "Multiple static call targets" and
result = count(CallExprBase call | multipleStaticCallTargets(call, _) | call)
or
type = "Multiple record fields" and
result = count(FieldExpr fe | multipleRecordFields(fe, _) | fe)
or
type = "Multiple tuple fields" and
result = count(FieldExpr fe | multipleTupleFields(fe, _) | fe)
}

View File

@@ -0,0 +1,334 @@
/** Provides classes representing types without type arguments. */
private import rust
private import PathResolution
private import TypeInference
private import TypeMention
private import codeql.rust.internal.CachedStages
cached
newtype TType =
TStruct(Struct s) { Stages::TypeInference::ref() } or
TEnum(Enum e) or
TTrait(Trait t) or
TImpl(Impl i) or
TArrayType() or // todo: add size?
TRefType() or // todo: add mut?
TTypeParamTypeParameter(TypeParam t) or
TRefTypeParameter() or
TSelfTypeParameter()
/**
* A type without type arguments.
*
* Note that this type includes things that, strictly speaking, are not Rust
* types, such as traits and implementation blocks.
*/
abstract class Type extends TType {
/** Gets the method `name` belonging to this type, if any. */
pragma[nomagic]
abstract Function getMethod(string name);
/** Gets the record field `name` belonging to this type, if any. */
pragma[nomagic]
abstract RecordField getRecordField(string name);
/** Gets the `i`th tuple field belonging to this type, if any. */
pragma[nomagic]
abstract TupleField getTupleField(int i);
/** Gets the `i`th type parameter of this type, if any. */
abstract TypeParameter getTypeParameter(int i);
/** Gets a type parameter of this type. */
final TypeParameter getATypeParameter() { result = this.getTypeParameter(_) }
/**
* Gets an AST node that mentions a base type of this type, if any.
*
* Although Rust doesn't have traditional OOP-style inheritance, we model trait
* bounds and `impl` blocks as base types. Example:
*
* ```rust
* trait T1 {}
*
* trait T2 {}
*
* trait T3 : T1, T2 {}
* // ^^ `this`
* // ^^ `result`
* // ^^ `result`
* ```
*/
abstract TypeMention getABaseTypeMention();
/** Gets a textual representation of this type. */
abstract string toString();
/** Gets the location of this type. */
abstract Location getLocation();
}
abstract private class StructOrEnumType extends Type {
abstract ItemNode asItemNode();
final override Function getMethod(string name) {
result = this.asItemNode().getASuccessor(name) and
exists(ImplOrTraitItemNode impl | result = impl.getAnAssocItem() |
impl instanceof Trait
or
impl.(ImplItemNode).isFullyParametric()
)
}
final override ImplMention getABaseTypeMention() {
this.asItemNode() = result.resolveSelfTy() and
result.isFullyParametric()
}
}
/** A struct type. */
class StructType extends StructOrEnumType, TStruct {
private Struct struct;
StructType() { this = TStruct(struct) }
override ItemNode asItemNode() { result = struct }
override RecordField getRecordField(string name) { result = struct.getRecordField(name) }
override TupleField getTupleField(int i) { result = struct.getTupleField(i) }
override TypeParameter getTypeParameter(int i) {
result = TTypeParamTypeParameter(struct.getGenericParamList().getTypeParam(i))
}
override string toString() { result = struct.toString() }
override Location getLocation() { result = struct.getLocation() }
}
/** An enum type. */
class EnumType extends StructOrEnumType, TEnum {
private Enum enum;
EnumType() { this = TEnum(enum) }
override ItemNode asItemNode() { result = enum }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) {
result = TTypeParamTypeParameter(enum.getGenericParamList().getTypeParam(i))
}
override string toString() { result = enum.toString() }
override Location getLocation() { result = enum.getLocation() }
}
/** A trait type. */
class TraitType extends Type, TTrait {
private Trait trait;
TraitType() { this = TTrait(trait) }
override Function getMethod(string name) { result = trait.(ItemNode).getASuccessor(name) }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) {
result = TTypeParamTypeParameter(trait.getGenericParamList().getTypeParam(i))
or
result = TSelfTypeParameter() and
i = -1
}
pragma[nomagic]
private TypeReprMention getABoundMention() {
result = trait.getTypeBoundList().getABound().getTypeRepr()
}
override TypeMention getABaseTypeMention() { result = this.getABoundMention() }
override string toString() { result = trait.toString() }
override Location getLocation() { result = trait.getLocation() }
}
/**
* An `impl` block type.
*
* Although `impl` blocks are not really types, we treat them as such in order
* to be able to match type parameters from structs (or enums) with type
* parameters from `impl` blocks. For example, in
*
* ```rust
* struct S<T1>(T1);
*
* impl<T2> S<T2> {
* fn id(self) -> S<T2> { self }
* }
*
* let x : S(i64) = S(42);
* x.id();
* ```
*
* we pretend that the `impl` block is a base type mention of the struct `S`,
* with type argument `T1`. This means that from knowing that `x` has type
* `S(i64)`, we can first match `i64` with `T1`, and then by matching `T1` with
* `T2`, we can match `i64` with `T2`.
*
* `impl` blocks can also have base type mentions, namely the trait that they
* implement (if any). Example:
*
* ```rust
* struct S<T1>(T1);
*
* trait Trait<T2> {
* fn f(self) -> T2;
*
* fn g(self) -> T2 { self.f() }
* }
*
* impl<T3> Trait<T3> for S<T3> { // `Trait<T3>` is a base type mention of this `impl` block
* fn f(self) -> T3 {
* match self {
* S(x) => x
* }
* }
* }
*
* let x : S(i64) = S(42);
* x.g();
* ```
*
* In this case we can match `i64` with `T1`, `T1` with `T3`, and `T3` with `T2`,
* allowing us match `i64` with `T2`, and hence infer that the return type of `g`
* is `i64`.
*/
class ImplType extends Type, TImpl {
private Impl impl;
ImplType() { this = TImpl(impl) }
override Function getMethod(string name) { result = impl.(ItemNode).getASuccessor(name) }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) {
result = TTypeParamTypeParameter(impl.getGenericParamList().getTypeParam(i))
or
result = TSelfTypeParameter() and
i = -1
}
override TypeMention getABaseTypeMention() { result = impl.getTrait() }
override string toString() { result = impl.toString() }
override Location getLocation() { result = impl.getLocation() }
}
/**
* An array type.
*
* Array types like `[i64; 5]` are modeled as normal generic types
* with a single type argument.
*/
class ArrayType extends Type, TArrayType {
ArrayType() { this = TArrayType() }
override Function getMethod(string name) { none() }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) {
none() // todo
}
override TypeMention getABaseTypeMention() { none() }
override string toString() { result = "[]" }
override Location getLocation() { result instanceof EmptyLocation }
}
/**
* A reference type.
*
* Reference types like `& i64` are modeled as normal generic types
* with a single type argument.
*/
class RefType extends Type, TRefType {
RefType() { this = TRefType() }
override Function getMethod(string name) { none() }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) {
result = TRefTypeParameter() and
i = 0
}
override TypeMention getABaseTypeMention() { none() }
override string toString() { result = "&" }
override Location getLocation() { result instanceof EmptyLocation }
}
/** A type parameter. */
abstract class TypeParameter extends Type {
override TypeMention getABaseTypeMention() { none() }
override RecordField getRecordField(string name) { none() }
override TupleField getTupleField(int i) { none() }
override TypeParameter getTypeParameter(int i) { none() }
}
/** A type parameter from source code. */
class TypeParamTypeParameter extends TypeParameter, TTypeParamTypeParameter {
private TypeParam typeParam;
TypeParamTypeParameter() { this = TTypeParamTypeParameter(typeParam) }
TypeParam getTypeParam() { result = typeParam }
override Function getMethod(string name) { result = typeParam.(ItemNode).getASuccessor(name) }
override string toString() { result = typeParam.toString() }
override Location getLocation() { result = typeParam.getLocation() }
}
/** An implicit reference type parameter. */
class RefTypeParameter extends TypeParameter, TRefTypeParameter {
override Function getMethod(string name) { none() }
override string toString() { result = "&T" }
override Location getLocation() { result instanceof EmptyLocation }
}
/** An implicit `Self` type parameter. */
class SelfTypeParameter extends TypeParameter, TSelfTypeParameter {
override Function getMethod(string name) { none() }
override string toString() { result = "(Self)" }
override Location getLocation() { result instanceof EmptyLocation }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
/**
* Provides classes for recognizing type inference inconsistencies.
*/
import TypeInference::Consistency

View File

@@ -0,0 +1,173 @@
/** Provides classes for representing type mentions, used in type inference. */
private import rust
private import Type
private import PathResolution
private import TypeInference
/** An AST node that may mention a type. */
abstract class TypeMention extends AstNode {
/** Gets the `i`th type argument mention, if any. */
abstract TypeMention getTypeArgument(int i);
/** Gets the type that this node resolves to, if any. */
abstract Type resolveType();
/** Gets the sub mention at `path`. */
pragma[nomagic]
private TypeMention getMentionAt(TypePath path) {
path.isEmpty() and
result = this
or
exists(int i, TypeParameter tp, TypeMention arg, TypePath suffix |
arg = this.getTypeArgument(pragma[only_bind_into](i)) and
result = arg.getMentionAt(suffix) and
path = TypePath::cons(tp, suffix) and
tp = this.resolveType().getTypeParameter(pragma[only_bind_into](i))
)
}
/** Gets the type that the sub mention at `path` resolves to, if any. */
Type resolveTypeAt(TypePath path) { result = this.getMentionAt(path).resolveType() }
/**
* Like `resolveTypeAt`, but also resolves `Self` mentions to the implicit
* `Self` type parameter.
*
* This is only needed when resolving types for calls to methods; inside the
* methods themselves, `Self` only resolves to the relevant trait or type
* being implemented.
*/
final Type resolveTypeAtInclSelf(TypePath path) {
result = this.resolveTypeAt(path)
or
exists(TypeMention tm, ImplOrTraitItemNode node |
tm = this.getMentionAt(path) and
result = TSelfTypeParameter()
|
tm = node.getASelfPath()
or
tm.(PathTypeRepr).getPath() = node.getASelfPath()
)
}
}
class TypeReprMention extends TypeMention, TypeRepr {
TypeReprMention() { not this instanceof InferTypeRepr }
override TypeReprMention getTypeArgument(int i) {
result = this.(ArrayTypeRepr).getElementTypeRepr() and
i = 0
or
result = this.(RefTypeRepr).getTypeRepr() and
i = 0
or
result = this.(PathTypeRepr).getPath().(PathMention).getTypeArgument(i)
}
override Type resolveType() {
this instanceof ArrayTypeRepr and
result = TArrayType()
or
this instanceof RefTypeRepr and
result = TRefType()
or
result = this.(PathTypeRepr).getPath().(PathMention).resolveType()
}
}
class PathMention extends TypeMention, Path {
override TypeMention getTypeArgument(int i) {
result = this.getPart().getGenericArgList().getTypeArg(i)
or
// `Self` paths inside traits and `impl` blocks have implicit type arguments
// that are the type parameters of the trait or impl. For example, in
//
// ```rust
// impl Foo<T> {
// fn m(self) -> Self {
// self
// }
// }
// ```
//
// the `Self` return type is shorthand for `Foo<T>`.
exists(ImplOrTraitItemNode node | this = node.getASelfPath() |
result = node.(ImplItemNode).getSelfPath().getPart().getGenericArgList().getTypeArg(i)
or
result = node.(Trait).getGenericParamList().getTypeParam(i)
)
}
override Type resolveType() {
exists(ItemNode i | i = resolvePath(this) |
result = TStruct(i)
or
result = TEnum(i)
or
result = TTrait(i)
or
result = TTypeParamTypeParameter(i)
or
result = i.(TypeAlias).getTypeRepr().(TypeReprMention).resolveType()
)
}
}
// Used to represent implicit `Self` type arguments in traits and `impl` blocks,
// see `PathMention` for details.
class TypeParamMention extends TypeMention, TypeParam {
override TypeReprMention getTypeArgument(int i) { none() }
override Type resolveType() { result = TTypeParamTypeParameter(this) }
}
/**
* Holds if the `i`th type argument of `selfPath`, belonging to `impl`, resolves
* to type parameter `tp`.
*
* Example:
*
* ```rust
* impl<T> Foo<T> for Bar<T> { ... }
* // ^^^^^^ selfPath
* // ^ tp
* ```
*/
pragma[nomagic]
private predicate isImplSelfTypeParam(
ImplItemNode impl, PathMention selfPath, int i, TypeParameter tp
) {
exists(PathMention path |
selfPath = impl.getSelfPath() and
path = selfPath.getPart().getGenericArgList().getTypeArg(i).(PathTypeRepr).getPath() and
tp = path.resolveType()
)
}
class ImplMention extends TypeMention, ImplItemNode {
override TypeReprMention getTypeArgument(int i) { none() }
override Type resolveType() { result = TImpl(this) }
override Type resolveTypeAt(TypePath path) {
result = TImpl(this) and
path.isEmpty()
or
// For example, in
//
// ```rust
// struct S<T1>(T1);
//
// impl<T2> S<T2> { ... }
// ```
//
// We get that the type path "0" resolves to `T1` for the `impl` block,
// which is considered a base type mention of `S`.
exists(PathMention selfPath, TypeParameter tp, int i |
isImplSelfTypeParam(this, selfPath, pragma[only_bind_into](i), tp) and
result = selfPath.resolveType().getTypeParameter(pragma[only_bind_into](i)) and
path = TypePath::singleton(tp)
)
}
}

View File

@@ -7,6 +7,7 @@ import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.security.SensitiveData
private import codeql.rust.Concepts
/**
* Provides default sources, sinks and barriers for detecting cleartext logging
@@ -21,7 +22,9 @@ module CleartextLogging {
/**
* A data flow sink for cleartext logging vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "CleartextLogging" }
}
/**
* A barrier for cleartext logging vulnerabilities.

View File

@@ -23,7 +23,9 @@ module SqlInjection {
/**
* A data flow sink for SQL injection vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "SqlInjection" }
}
/**
* A barrier for SQL injection vulnerabilities.

View File

@@ -43,7 +43,7 @@ module NormalHashFunction {
* data" vulnerabilities that applies to data that does not require computationally expensive
* hashing. That is, a broken or weak hashing algorithm.
*/
abstract class Sink extends DataFlow::Node {
abstract class Sink extends QuerySink::Range {
/**
* Gets the name of the weak hashing algorithm.
*/
@@ -76,6 +76,8 @@ module NormalHashFunction {
class WeakHashingOperationInputAsSink extends Sink {
Cryptography::HashingAlgorithm algorithm;
override string getSinkType() { result = "WeakSensitiveDataHashing" }
WeakHashingOperationInputAsSink() {
exists(Cryptography::CryptographicOperation operation |
algorithm.isWeak() and
@@ -114,7 +116,9 @@ module ComputationallyExpensiveHashFunction {
* hashing. That is, a broken or weak hashing algorithm or one that is not computationally
* expensive enough for password hashing.
*/
abstract class Sink extends DataFlow::Node {
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "WeakSensitiveDataHashing" }
/**
* Gets the name of the weak hashing algorithm.
*/

View File

@@ -8,11 +8,14 @@ private import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.controlflow.CfgNodes
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts
/**
* A data flow sink for regular expression injection vulnerabilities.
*/
abstract class RegexInjectionSink extends DataFlow::Node { }
abstract class RegexInjectionSink extends QuerySink::Range {
override string getSinkType() { result = "RegexInjection" }
}
/**
* A barrier for regular expression injection vulnerabilities.

View File

@@ -12,6 +12,7 @@ dependencies:
codeql/mad: ${workspace}
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/typeinference: ${workspace}
codeql/util: ${workspace}
dataExtensions:
- /**/*.model.yml

View File

@@ -10,8 +10,9 @@
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.Concepts
import Stats
from string kind, int num
where num = strictcount(DataFlow::Node n | getAQuerySinkKind(n) = kind)
where num = strictcount(QuerySink s | s.getSinkType() = kind)
select kind, num

View File

@@ -11,7 +11,8 @@
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.Concepts
import Stats
from DataFlow::Node n
select n, "Sink for " + strictconcat(getAQuerySinkKind(n), ", ") + "."
from QuerySink s
select s, "Sink for " + concat(s.getSinkType(), ", ") + "."

View File

@@ -7,10 +7,15 @@ private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.rust.internal.AstConsistency as AstConsistency
private import codeql.rust.internal.PathResolutionConsistency as PathResolutionConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency
private import codeql.rust.security.SqlInjectionExtensions
private import codeql.rust.Concepts
// import all query extensions files, so that all extensions of `QuerySink` are found
private import codeql.rust.security.CleartextLoggingExtensions
private import codeql.rust.security.SqlInjectionExtensions
private import codeql.rust.security.WeakSensitiveDataHashingExtensions
private import codeql.rust.security.regex.RegexInjectionExtensions
/**
* Gets a count of the total number of lines of code in the database.
@@ -31,6 +36,14 @@ int getTotalAstInconsistencies() {
result = sum(string type | | AstConsistency::getAstInconsistencyCounts(type))
}
/**
* Gets a count of the total number of path resolution inconsistencies in the database.
*/
int getTotalPathResolutionInconsistencies() {
result =
sum(string type | | PathResolutionConsistency::getPathResolutionInconsistencyCounts(type))
}
/**
* Gets a count of the total number of control flow graph inconsistencies in the database.
*/
@@ -55,16 +68,7 @@ int getTaintEdgesCount() {
)
}
/**
* Gets a kind of query for which `n` is a sink (if any).
*/
string getAQuerySinkKind(DataFlow::Node n) {
n instanceof SqlInjection::Sink and result = "SqlInjection"
or
n instanceof CleartextLogging::Sink and result = "CleartextLogging"
}
/**
* Gets a count of the total number of query sinks in the database.
*/
int getQuerySinksCount() { result = count(DataFlow::Node n | exists(getAQuerySinkKind(n))) }
int getQuerySinksCount() { result = count(QuerySink s) }

View File

@@ -54,6 +54,8 @@ where
or
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
or
key = "Inconsistencies - Path resolution" and value = getTotalPathResolutionInconsistencies()
or
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
or
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()

View File

@@ -1 +1 @@
| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:14:10:30 | GenericParamList |
| gen_trait.rs:10:1:10:57 | trait Foo | gen_trait.rs:10:14:10:30 | <...> |

View File

@@ -4,7 +4,7 @@
| utf8_identifiers.rs:1:1:4:6 | fn foo |
| utf8_identifiers.rs:1:1:12:2 | SourceFile |
| utf8_identifiers.rs:1:4:1:6 | foo |
| utf8_identifiers.rs:1:7:4:1 | GenericParamList |
| utf8_identifiers.rs:1:7:4:1 | <...> |
| utf8_identifiers.rs:2:5:2:6 | ''\u03b2 |
| utf8_identifiers.rs:2:5:2:6 | LifetimeParam |
| utf8_identifiers.rs:3:5:3:5 | \u03b3 |

View File

@@ -60,28 +60,21 @@ edges
| main.rs:134:24:134:33 | source(...) | main.rs:134:13:134:34 | ...::new(...) [MyInt] | provenance | |
| main.rs:135:9:135:26 | MyInt {...} [MyInt] | main.rs:135:24:135:24 | m | provenance | |
| main.rs:135:24:135:24 | m | main.rs:136:10:136:10 | m | provenance | |
| main.rs:175:18:175:21 | SelfParam [MyInt] | main.rs:175:48:177:5 | { ... } [MyInt] | provenance | |
| main.rs:179:26:179:37 | ...: MyInt [MyInt] | main.rs:179:49:181:5 | { ... } [MyInt] | provenance | |
| main.rs:185:9:185:9 | a [MyInt] | main.rs:187:49:187:49 | a [MyInt] | provenance | |
| main.rs:185:13:185:38 | MyInt {...} [MyInt] | main.rs:185:9:185:9 | a [MyInt] | provenance | |
| main.rs:185:28:185:36 | source(...) | main.rs:185:13:185:38 | MyInt {...} [MyInt] | provenance | |
| main.rs:187:9:187:26 | MyInt {...} [MyInt] | main.rs:187:24:187:24 | c | provenance | |
| main.rs:187:24:187:24 | c | main.rs:188:10:188:10 | c | provenance | |
| main.rs:187:30:187:53 | ...::take_self(...) [MyInt] | main.rs:187:9:187:26 | MyInt {...} [MyInt] | provenance | |
| main.rs:187:49:187:49 | a [MyInt] | main.rs:175:18:175:21 | SelfParam [MyInt] | provenance | |
| main.rs:187:49:187:49 | a [MyInt] | main.rs:187:30:187:53 | ...::take_self(...) [MyInt] | provenance | |
| main.rs:191:9:191:9 | b [MyInt] | main.rs:192:54:192:54 | b [MyInt] | provenance | |
| main.rs:191:13:191:39 | MyInt {...} [MyInt] | main.rs:191:9:191:9 | b [MyInt] | provenance | |
| main.rs:191:28:191:37 | source(...) | main.rs:191:13:191:39 | MyInt {...} [MyInt] | provenance | |
| main.rs:192:9:192:26 | MyInt {...} [MyInt] | main.rs:192:24:192:24 | c | provenance | |
| main.rs:192:24:192:24 | c | main.rs:193:10:193:10 | c | provenance | |
| main.rs:192:30:192:55 | ...::take_second(...) [MyInt] | main.rs:192:9:192:26 | MyInt {...} [MyInt] | provenance | |
| main.rs:192:54:192:54 | b [MyInt] | main.rs:179:26:179:37 | ...: MyInt [MyInt] | provenance | |
| main.rs:192:54:192:54 | b [MyInt] | main.rs:192:30:192:55 | ...::take_second(...) [MyInt] | provenance | |
| main.rs:202:9:202:9 | a | main.rs:203:10:203:10 | a | provenance | |
| main.rs:202:13:202:21 | source(...) | main.rs:202:9:202:9 | a | provenance | |
| main.rs:212:13:212:13 | c | main.rs:213:14:213:14 | c | provenance | |
| main.rs:212:17:212:25 | source(...) | main.rs:212:13:212:13 | c | provenance | |
| main.rs:142:12:142:15 | SelfParam [MyInt] | main.rs:144:24:144:27 | self [MyInt] | provenance | |
| main.rs:144:9:144:35 | MyInt {...} [MyInt] | main.rs:142:42:145:5 | { ... } [MyInt] | provenance | |
| main.rs:144:24:144:27 | self [MyInt] | main.rs:144:24:144:33 | self.value | provenance | |
| main.rs:144:24:144:33 | self.value | main.rs:144:9:144:35 | MyInt {...} [MyInt] | provenance | |
| main.rs:159:9:159:9 | a [MyInt] | main.rs:142:12:142:15 | SelfParam [MyInt] | provenance | |
| main.rs:159:9:159:9 | a [MyInt] | main.rs:161:13:161:20 | a.add(...) [MyInt] | provenance | |
| main.rs:159:13:159:38 | MyInt {...} [MyInt] | main.rs:159:9:159:9 | a [MyInt] | provenance | |
| main.rs:159:28:159:36 | source(...) | main.rs:159:13:159:38 | MyInt {...} [MyInt] | provenance | |
| main.rs:161:9:161:9 | d [MyInt] | main.rs:162:10:162:10 | d [MyInt] | provenance | |
| main.rs:161:13:161:20 | a.add(...) [MyInt] | main.rs:161:9:161:9 | d [MyInt] | provenance | |
| main.rs:162:10:162:10 | d [MyInt] | main.rs:162:10:162:16 | d.value | provenance | |
| main.rs:201:9:201:9 | a | main.rs:202:10:202:10 | a | provenance | |
| main.rs:201:13:201:21 | source(...) | main.rs:201:9:201:9 | a | provenance | |
| main.rs:211:13:211:13 | c | main.rs:212:14:212:14 | c | provenance | |
| main.rs:211:17:211:25 | source(...) | main.rs:211:13:211:13 | c | provenance | |
nodes
| main.rs:12:28:14:1 | { ... } | semmle.label | { ... } |
| main.rs:13:5:13:13 | source(...) | semmle.label | source(...) |
@@ -151,32 +144,24 @@ nodes
| main.rs:135:9:135:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:135:24:135:24 | m | semmle.label | m |
| main.rs:136:10:136:10 | m | semmle.label | m |
| main.rs:175:18:175:21 | SelfParam [MyInt] | semmle.label | SelfParam [MyInt] |
| main.rs:175:48:177:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] |
| main.rs:179:26:179:37 | ...: MyInt [MyInt] | semmle.label | ...: MyInt [MyInt] |
| main.rs:179:49:181:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] |
| main.rs:185:9:185:9 | a [MyInt] | semmle.label | a [MyInt] |
| main.rs:185:13:185:38 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:185:28:185:36 | source(...) | semmle.label | source(...) |
| main.rs:187:9:187:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:187:24:187:24 | c | semmle.label | c |
| main.rs:187:30:187:53 | ...::take_self(...) [MyInt] | semmle.label | ...::take_self(...) [MyInt] |
| main.rs:187:49:187:49 | a [MyInt] | semmle.label | a [MyInt] |
| main.rs:188:10:188:10 | c | semmle.label | c |
| main.rs:191:9:191:9 | b [MyInt] | semmle.label | b [MyInt] |
| main.rs:191:13:191:39 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:191:28:191:37 | source(...) | semmle.label | source(...) |
| main.rs:192:9:192:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:192:24:192:24 | c | semmle.label | c |
| main.rs:192:30:192:55 | ...::take_second(...) [MyInt] | semmle.label | ...::take_second(...) [MyInt] |
| main.rs:192:54:192:54 | b [MyInt] | semmle.label | b [MyInt] |
| main.rs:193:10:193:10 | c | semmle.label | c |
| main.rs:202:9:202:9 | a | semmle.label | a |
| main.rs:202:13:202:21 | source(...) | semmle.label | source(...) |
| main.rs:203:10:203:10 | a | semmle.label | a |
| main.rs:212:13:212:13 | c | semmle.label | c |
| main.rs:212:17:212:25 | source(...) | semmle.label | source(...) |
| main.rs:213:14:213:14 | c | semmle.label | c |
| main.rs:142:12:142:15 | SelfParam [MyInt] | semmle.label | SelfParam [MyInt] |
| main.rs:142:42:145:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] |
| main.rs:144:9:144:35 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:144:24:144:27 | self [MyInt] | semmle.label | self [MyInt] |
| main.rs:144:24:144:33 | self.value | semmle.label | self.value |
| main.rs:159:9:159:9 | a [MyInt] | semmle.label | a [MyInt] |
| main.rs:159:13:159:38 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
| main.rs:159:28:159:36 | source(...) | semmle.label | source(...) |
| main.rs:161:9:161:9 | d [MyInt] | semmle.label | d [MyInt] |
| main.rs:161:13:161:20 | a.add(...) [MyInt] | semmle.label | a.add(...) [MyInt] |
| main.rs:162:10:162:10 | d [MyInt] | semmle.label | d [MyInt] |
| main.rs:162:10:162:16 | d.value | semmle.label | d.value |
| main.rs:201:9:201:9 | a | semmle.label | a |
| main.rs:201:13:201:21 | source(...) | semmle.label | source(...) |
| main.rs:202:10:202:10 | a | semmle.label | a |
| main.rs:211:13:211:13 | c | semmle.label | c |
| main.rs:211:17:211:25 | source(...) | semmle.label | source(...) |
| main.rs:212:14:212:14 | c | semmle.label | c |
subpaths
| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:36:13:36:27 | pass_through(...) |
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) |
@@ -184,8 +169,7 @@ subpaths
| main.rs:103:29:103:29 | a | main.rs:79:27:79:32 | ...: i64 | main.rs:79:42:85:5 | { ... } | main.rs:103:13:103:30 | mn.data_through(...) |
| main.rs:116:38:116:38 | a | main.rs:79:27:79:32 | ...: i64 | main.rs:79:42:85:5 | { ... } | main.rs:116:13:116:39 | ...::data_through(...) |
| main.rs:134:24:134:33 | source(...) | main.rs:128:12:128:17 | ...: i64 | main.rs:128:28:130:5 | { ... } [MyInt] | main.rs:134:13:134:34 | ...::new(...) [MyInt] |
| main.rs:187:49:187:49 | a [MyInt] | main.rs:175:18:175:21 | SelfParam [MyInt] | main.rs:175:48:177:5 | { ... } [MyInt] | main.rs:187:30:187:53 | ...::take_self(...) [MyInt] |
| main.rs:192:54:192:54 | b [MyInt] | main.rs:179:26:179:37 | ...: MyInt [MyInt] | main.rs:179:49:181:5 | { ... } [MyInt] | main.rs:192:30:192:55 | ...::take_second(...) [MyInt] |
| main.rs:159:9:159:9 | a [MyInt] | main.rs:142:12:142:15 | SelfParam [MyInt] | main.rs:142:42:145:5 | { ... } [MyInt] | main.rs:161:13:161:20 | a.add(...) [MyInt] |
testFailures
#select
| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) |
@@ -199,7 +183,6 @@ testFailures
| main.rs:104:10:104:10 | b | main.rs:102:13:102:21 | source(...) | main.rs:104:10:104:10 | b | $@ | main.rs:102:13:102:21 | source(...) | source(...) |
| main.rs:117:10:117:10 | b | main.rs:115:13:115:22 | source(...) | main.rs:117:10:117:10 | b | $@ | main.rs:115:13:115:22 | source(...) | source(...) |
| main.rs:136:10:136:10 | m | main.rs:134:24:134:33 | source(...) | main.rs:136:10:136:10 | m | $@ | main.rs:134:24:134:33 | source(...) | source(...) |
| main.rs:188:10:188:10 | c | main.rs:185:28:185:36 | source(...) | main.rs:188:10:188:10 | c | $@ | main.rs:185:28:185:36 | source(...) | source(...) |
| main.rs:193:10:193:10 | c | main.rs:191:28:191:37 | source(...) | main.rs:193:10:193:10 | c | $@ | main.rs:191:28:191:37 | source(...) | source(...) |
| main.rs:203:10:203:10 | a | main.rs:202:13:202:21 | source(...) | main.rs:203:10:203:10 | a | $@ | main.rs:202:13:202:21 | source(...) | source(...) |
| main.rs:213:14:213:14 | c | main.rs:212:17:212:25 | source(...) | main.rs:213:14:213:14 | c | $@ | main.rs:212:17:212:25 | source(...) | source(...) |
| main.rs:162:10:162:16 | d.value | main.rs:159:28:159:36 | source(...) | main.rs:162:10:162:16 | d.value | $@ | main.rs:159:28:159:36 | source(...) | source(...) |
| main.rs:202:10:202:10 | a | main.rs:201:13:201:21 | source(...) | main.rs:202:10:202:10 | a | $@ | main.rs:201:13:201:21 | source(...) | source(...) |
| main.rs:212:14:212:14 | c | main.rs:211:17:211:25 | source(...) | main.rs:212:14:212:14 | c | $@ | main.rs:211:17:211:25 | source(...) | source(...) |

View File

@@ -159,8 +159,7 @@ fn test_operator_overloading() {
let a = MyInt { value: source(7) };
let b = MyInt { value: 2 };
let d = a.add(b);
sink(d.value); // $ MISSING: hasValueFlow=7
sink(d.value); // $ hasValueFlow=7
}
trait MyTrait {
@@ -185,12 +184,12 @@ fn data_through_trait_method_called_as_function() {
let a = MyInt { value: source(8) };
let b = MyInt { value: 2 };
let MyInt { value: c } = MyTrait::take_self(a, b);
sink(c); // $ hasValueFlow=8
sink(c); // $ MISSING: hasValueFlow=8
let a = MyInt { value: 0 };
let b = MyInt { value: source(37) };
let MyInt { value: c } = MyTrait::take_second(a, b);
sink(c); // $ hasValueFlow=37
sink(c); // $ MISSING: hasValueFlow=37
let a = MyInt { value: 0 };
let b = MyInt { value: source(38) };

View File

@@ -37,31 +37,28 @@
| main.rs:159:28:159:36 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:161:13:161:20 | a.add(...) | main.rs:142:5:145:5 | fn add |
| main.rs:162:5:162:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:185:28:185:36 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:187:30:187:53 | ...::take_self(...) | main.rs:175:5:177:5 | fn take_self |
| main.rs:188:5:188:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:191:28:191:37 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:192:30:192:55 | ...::take_second(...) | main.rs:179:5:181:5 | fn take_second |
| main.rs:193:5:193:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:196:28:196:37 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:197:30:197:53 | ...::take_self(...) | main.rs:175:5:177:5 | fn take_self |
| main.rs:198:5:198:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:202:13:202:21 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:203:5:203:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:208:13:208:26 | async_source(...) | main.rs:201:1:205:1 | fn async_source |
| main.rs:209:5:209:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:212:17:212:25 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:213:9:213:15 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:216:5:216:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:220:41:220:54 | async_source(...) | main.rs:201:1:205:1 | fn async_source |
| main.rs:221:5:221:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:223:33:223:61 | test_async_await_async_part(...) | main.rs:207:1:217:1 | fn test_async_await_async_part |
| main.rs:227:5:227:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call |
| main.rs:228:5:228:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call |
| main.rs:229:5:229:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call |
| main.rs:230:5:230:34 | data_through_nested_function(...) | main.rs:48:1:57:1 | fn data_through_nested_function |
| main.rs:232:5:232:24 | data_out_of_method(...) | main.rs:88:1:92:1 | fn data_out_of_method |
| main.rs:233:5:233:28 | data_in_to_method_call(...) | main.rs:94:1:98:1 | fn data_in_to_method_call |
| main.rs:234:5:234:25 | data_through_method(...) | main.rs:100:1:105:1 | fn data_through_method |
| main.rs:236:5:236:31 | test_operator_overloading(...) | main.rs:148:1:164:1 | fn test_operator_overloading |
| main.rs:237:5:237:22 | test_async_await(...) | main.rs:219:1:224:1 | fn test_async_await |
| main.rs:184:28:184:36 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:187:5:187:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:190:28:190:37 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:192:5:192:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:195:28:195:37 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:197:5:197:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:201:13:201:21 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:202:5:202:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:207:13:207:26 | async_source(...) | main.rs:200:1:204:1 | fn async_source |
| main.rs:208:5:208:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:211:17:211:25 | source(...) | main.rs:1:1:3:1 | fn source |
| main.rs:212:9:212:15 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:215:5:215:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:219:41:219:54 | async_source(...) | main.rs:200:1:204:1 | fn async_source |
| main.rs:220:5:220:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
| main.rs:222:33:222:61 | test_async_await_async_part(...) | main.rs:206:1:216:1 | fn test_async_await_async_part |
| main.rs:226:5:226:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call |
| main.rs:227:5:227:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call |
| main.rs:228:5:228:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call |
| main.rs:229:5:229:34 | data_through_nested_function(...) | main.rs:48:1:57:1 | fn data_through_nested_function |
| main.rs:231:5:231:24 | data_out_of_method(...) | main.rs:88:1:92:1 | fn data_out_of_method |
| main.rs:232:5:232:28 | data_in_to_method_call(...) | main.rs:94:1:98:1 | fn data_in_to_method_call |
| main.rs:233:5:233:25 | data_through_method(...) | main.rs:100:1:105:1 | fn data_through_method |
| main.rs:235:5:235:31 | test_operator_overloading(...) | main.rs:148:1:163:1 | fn test_operator_overloading |
| main.rs:236:5:236:22 | test_async_await(...) | main.rs:218:1:223:1 | fn test_async_await |

View File

@@ -2321,6 +2321,7 @@ storeStep
| main.rs:137:38:137:38 | 2 | Point.y | main.rs:137:13:137:40 | Point {...} |
| main.rs:143:28:143:36 | source(...) | Point.x | main.rs:143:17:143:44 | Point {...} |
| main.rs:143:42:143:42 | 2 | Point.y | main.rs:143:17:143:44 | Point {...} |
| main.rs:145:11:145:20 | source(...) | Point.y | main.rs:145:5:145:5 | [post] p |
| main.rs:151:12:151:21 | source(...) | Point.x | main.rs:150:13:153:5 | Point {...} |
| main.rs:152:12:152:12 | 2 | Point.y | main.rs:150:13:153:5 | Point {...} |
| main.rs:166:16:169:9 | Point {...} | Point3D.plane | main.rs:165:13:171:5 | Point3D {...} |
@@ -2956,13 +2957,25 @@ readStep
| main.rs:124:10:124:10 | b | tuple.0 | main.rs:124:10:124:12 | b.0 |
| main.rs:124:10:124:12 | b.0 | tuple.1 | main.rs:124:10:124:15 | ... .1 |
| main.rs:125:10:125:10 | b | tuple.1 | main.rs:125:10:125:12 | b.1 |
| main.rs:138:10:138:10 | p | Point.x | main.rs:138:10:138:12 | p.x |
| main.rs:139:10:139:10 | p | Point.y | main.rs:139:10:139:12 | p.y |
| main.rs:144:10:144:10 | p | Point.y | main.rs:144:10:144:12 | p.y |
| main.rs:145:5:145:5 | p | Point.y | main.rs:145:5:145:7 | p.y |
| main.rs:146:10:146:10 | p | Point.y | main.rs:146:10:146:12 | p.y |
| main.rs:154:9:154:28 | Point {...} | Point.x | main.rs:154:20:154:20 | a |
| main.rs:154:9:154:28 | Point {...} | Point.y | main.rs:154:26:154:26 | b |
| main.rs:172:10:172:10 | p | Point3D.plane | main.rs:172:10:172:16 | p.plane |
| main.rs:172:10:172:16 | p.plane | Point.x | main.rs:172:10:172:18 | ... .x |
| main.rs:173:10:173:10 | p | Point3D.plane | main.rs:173:10:173:16 | p.plane |
| main.rs:173:10:173:16 | p.plane | Point.y | main.rs:173:10:173:18 | ... .y |
| main.rs:174:10:174:10 | p | Point3D.z | main.rs:174:10:174:12 | p.z |
| main.rs:184:9:187:9 | Point3D {...} | Point3D.plane | main.rs:185:20:185:33 | Point {...} |
| main.rs:184:9:187:9 | Point3D {...} | Point3D.z | main.rs:186:13:186:13 | z |
| main.rs:185:20:185:33 | Point {...} | Point.x | main.rs:185:28:185:28 | x |
| main.rs:185:20:185:33 | Point {...} | Point.y | main.rs:185:31:185:31 | y |
| main.rs:199:10:199:10 | s | MyTupleStruct(0) | main.rs:199:10:199:12 | s.0 |
| main.rs:199:10:199:10 | s | tuple.0 | main.rs:199:10:199:12 | s.0 |
| main.rs:200:10:200:10 | s | MyTupleStruct(1) | main.rs:200:10:200:12 | s.1 |
| main.rs:200:10:200:10 | s | tuple.1 | main.rs:200:10:200:12 | s.1 |
| main.rs:203:9:203:27 | MyTupleStruct(...) | MyTupleStruct(0) | main.rs:203:23:203:23 | x |
| main.rs:203:9:203:27 | MyTupleStruct(...) | MyTupleStruct(1) | main.rs:203:26:203:26 | y |

View File

@@ -46,11 +46,24 @@ edges
| main.rs:122:14:122:14 | a [tuple.1] | main.rs:122:13:122:18 | TupleExpr [tuple.0, tuple.1] | provenance | |
| main.rs:124:10:124:10 | b [tuple.0, tuple.1] | main.rs:124:10:124:12 | b.0 [tuple.1] | provenance | |
| main.rs:124:10:124:12 | b.0 [tuple.1] | main.rs:124:10:124:15 | ... .1 | provenance | |
| main.rs:137:9:137:9 | p [Point.x] | main.rs:138:10:138:10 | p [Point.x] | provenance | |
| main.rs:137:13:137:40 | Point {...} [Point.x] | main.rs:137:9:137:9 | p [Point.x] | provenance | |
| main.rs:137:24:137:32 | source(...) | main.rs:137:13:137:40 | Point {...} [Point.x] | provenance | |
| main.rs:138:10:138:10 | p [Point.x] | main.rs:138:10:138:12 | p.x | provenance | |
| main.rs:145:5:145:5 | [post] p [Point.y] | main.rs:146:10:146:10 | p [Point.y] | provenance | |
| main.rs:145:11:145:20 | source(...) | main.rs:145:5:145:5 | [post] p [Point.y] | provenance | |
| main.rs:146:10:146:10 | p [Point.y] | main.rs:146:10:146:12 | p.y | provenance | |
| main.rs:150:9:150:9 | p [Point.x] | main.rs:154:9:154:28 | Point {...} [Point.x] | provenance | |
| main.rs:150:13:153:5 | Point {...} [Point.x] | main.rs:150:9:150:9 | p [Point.x] | provenance | |
| main.rs:151:12:151:21 | source(...) | main.rs:150:13:153:5 | Point {...} [Point.x] | provenance | |
| main.rs:154:9:154:28 | Point {...} [Point.x] | main.rs:154:20:154:20 | a | provenance | |
| main.rs:154:20:154:20 | a | main.rs:155:10:155:10 | a | provenance | |
| main.rs:165:9:165:9 | p [Point3D.plane, Point.y] | main.rs:173:10:173:10 | p [Point3D.plane, Point.y] | provenance | |
| main.rs:165:13:171:5 | Point3D {...} [Point3D.plane, Point.y] | main.rs:165:9:165:9 | p [Point3D.plane, Point.y] | provenance | |
| main.rs:166:16:169:9 | Point {...} [Point.y] | main.rs:165:13:171:5 | Point3D {...} [Point3D.plane, Point.y] | provenance | |
| main.rs:168:16:168:25 | source(...) | main.rs:166:16:169:9 | Point {...} [Point.y] | provenance | |
| main.rs:173:10:173:10 | p [Point3D.plane, Point.y] | main.rs:173:10:173:16 | p.plane [Point.y] | provenance | |
| main.rs:173:10:173:16 | p.plane [Point.y] | main.rs:173:10:173:18 | ... .y | provenance | |
| main.rs:178:9:178:9 | y | main.rs:180:30:180:30 | y | provenance | |
| main.rs:178:13:178:22 | source(...) | main.rs:178:9:178:9 | y | provenance | |
| main.rs:179:9:179:9 | p [Point3D.plane, Point.y] | main.rs:183:11:183:11 | p [Point3D.plane, Point.y] | provenance | |
@@ -61,9 +74,11 @@ edges
| main.rs:184:9:187:9 | Point3D {...} [Point3D.plane, Point.y] | main.rs:185:20:185:33 | Point {...} [Point.y] | provenance | |
| main.rs:185:20:185:33 | Point {...} [Point.y] | main.rs:185:31:185:31 | y | provenance | |
| main.rs:185:31:185:31 | y | main.rs:189:18:189:18 | y | provenance | |
| main.rs:198:9:198:9 | s [MyTupleStruct(0)] | main.rs:199:10:199:10 | s [MyTupleStruct(0)] | provenance | |
| main.rs:198:9:198:9 | s [MyTupleStruct(0)] | main.rs:202:11:202:11 | s [MyTupleStruct(0)] | provenance | |
| main.rs:198:13:198:40 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:198:9:198:9 | s [MyTupleStruct(0)] | provenance | |
| main.rs:198:27:198:36 | source(...) | main.rs:198:13:198:40 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | |
| main.rs:199:10:199:10 | s [MyTupleStruct(0)] | main.rs:199:10:199:12 | s.0 | provenance | |
| main.rs:202:11:202:11 | s [MyTupleStruct(0)] | main.rs:203:9:203:27 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | |
| main.rs:203:9:203:27 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:203:23:203:23 | x | provenance | |
| main.rs:203:23:203:23 | x | main.rs:204:18:204:18 | x | provenance | |
@@ -264,12 +279,28 @@ nodes
| main.rs:124:10:124:10 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] |
| main.rs:124:10:124:12 | b.0 [tuple.1] | semmle.label | b.0 [tuple.1] |
| main.rs:124:10:124:15 | ... .1 | semmle.label | ... .1 |
| main.rs:137:9:137:9 | p [Point.x] | semmle.label | p [Point.x] |
| main.rs:137:13:137:40 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] |
| main.rs:137:24:137:32 | source(...) | semmle.label | source(...) |
| main.rs:138:10:138:10 | p [Point.x] | semmle.label | p [Point.x] |
| main.rs:138:10:138:12 | p.x | semmle.label | p.x |
| main.rs:145:5:145:5 | [post] p [Point.y] | semmle.label | [post] p [Point.y] |
| main.rs:145:11:145:20 | source(...) | semmle.label | source(...) |
| main.rs:146:10:146:10 | p [Point.y] | semmle.label | p [Point.y] |
| main.rs:146:10:146:12 | p.y | semmle.label | p.y |
| main.rs:150:9:150:9 | p [Point.x] | semmle.label | p [Point.x] |
| main.rs:150:13:153:5 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] |
| main.rs:151:12:151:21 | source(...) | semmle.label | source(...) |
| main.rs:154:9:154:28 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] |
| main.rs:154:20:154:20 | a | semmle.label | a |
| main.rs:155:10:155:10 | a | semmle.label | a |
| main.rs:165:9:165:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] |
| main.rs:165:13:171:5 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] |
| main.rs:166:16:169:9 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] |
| main.rs:168:16:168:25 | source(...) | semmle.label | source(...) |
| main.rs:173:10:173:10 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] |
| main.rs:173:10:173:16 | p.plane [Point.y] | semmle.label | p.plane [Point.y] |
| main.rs:173:10:173:18 | ... .y | semmle.label | ... .y |
| main.rs:178:9:178:9 | y | semmle.label | y |
| main.rs:178:13:178:22 | source(...) | semmle.label | source(...) |
| main.rs:179:9:179:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] |
@@ -284,6 +315,8 @@ nodes
| main.rs:198:9:198:9 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] |
| main.rs:198:13:198:40 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] |
| main.rs:198:27:198:36 | source(...) | semmle.label | source(...) |
| main.rs:199:10:199:10 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] |
| main.rs:199:10:199:12 | s.0 | semmle.label | s.0 |
| main.rs:202:11:202:11 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] |
| main.rs:203:9:203:27 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] |
| main.rs:203:23:203:23 | x | semmle.label | x |
@@ -478,8 +511,12 @@ testFailures
| main.rs:113:10:113:12 | a.1 | main.rs:111:21:111:30 | source(...) | main.rs:113:10:113:12 | a.1 | $@ | main.rs:111:21:111:30 | source(...) | source(...) |
| main.rs:116:10:116:12 | a.0 | main.rs:114:11:114:20 | source(...) | main.rs:116:10:116:12 | a.0 | $@ | main.rs:114:11:114:20 | source(...) | source(...) |
| main.rs:124:10:124:15 | ... .1 | main.rs:121:17:121:26 | source(...) | main.rs:124:10:124:15 | ... .1 | $@ | main.rs:121:17:121:26 | source(...) | source(...) |
| main.rs:138:10:138:12 | p.x | main.rs:137:24:137:32 | source(...) | main.rs:138:10:138:12 | p.x | $@ | main.rs:137:24:137:32 | source(...) | source(...) |
| main.rs:146:10:146:12 | p.y | main.rs:145:11:145:20 | source(...) | main.rs:146:10:146:12 | p.y | $@ | main.rs:145:11:145:20 | source(...) | source(...) |
| main.rs:155:10:155:10 | a | main.rs:151:12:151:21 | source(...) | main.rs:155:10:155:10 | a | $@ | main.rs:151:12:151:21 | source(...) | source(...) |
| main.rs:173:10:173:18 | ... .y | main.rs:168:16:168:25 | source(...) | main.rs:173:10:173:18 | ... .y | $@ | main.rs:168:16:168:25 | source(...) | source(...) |
| main.rs:189:18:189:18 | y | main.rs:178:13:178:22 | source(...) | main.rs:189:18:189:18 | y | $@ | main.rs:178:13:178:22 | source(...) | source(...) |
| main.rs:199:10:199:12 | s.0 | main.rs:198:27:198:36 | source(...) | main.rs:199:10:199:12 | s.0 | $@ | main.rs:198:27:198:36 | source(...) | source(...) |
| main.rs:204:18:204:18 | x | main.rs:198:27:198:36 | source(...) | main.rs:204:18:204:18 | x | $@ | main.rs:198:27:198:36 | source(...) | source(...) |
| main.rs:217:33:217:33 | n | main.rs:214:27:214:36 | source(...) | main.rs:217:33:217:33 | n | $@ | main.rs:214:27:214:36 | source(...) | source(...) |
| main.rs:230:25:230:25 | n | main.rs:227:19:227:28 | source(...) | main.rs:230:25:230:25 | n | $@ | main.rs:227:19:227:28 | source(...) | source(...) |

View File

@@ -135,7 +135,7 @@ struct Point {
fn struct_field() {
let p = Point { x: source(9), y: 2 };
sink(p.x); // $ MISSING: hasValueFlow=9
sink(p.x); // $ hasValueFlow=9
sink(p.y);
}
@@ -143,7 +143,7 @@ fn struct_mutation() {
let mut p = Point { x: source(9), y: 2 };
sink(p.y);
p.y = source(54);
sink(p.y); // $ MISSING: hasValueFlow=54
sink(p.y); // $ hasValueFlow=54
}
fn struct_pattern_match() {
@@ -170,7 +170,7 @@ fn struct_nested_field() {
z: 4,
};
sink(p.plane.x);
sink(p.plane.y); // $ MISSING: hasValueFlow=77
sink(p.plane.y); // $ hasValueFlow=77
sink(p.z);
}
@@ -196,7 +196,7 @@ struct MyTupleStruct(i64, i64);
fn tuple_struct() {
let s = MyTupleStruct(source(94), 2);
sink(s.0); // $ MISSING: hasValueFlow=94
sink(s.0); // $ hasValueFlow=94
sink(s.1);
match s {

View File

@@ -126,7 +126,7 @@ fn test_set_struct_field() {
let s = source(7);
let my_struct = set_struct_field(s);
sink(my_struct.field1);
sink(my_struct.field2); // $ MISSING: hasValueFlow=7
sink(my_struct.field2); // $ hasValueFlow=7
}
// has a flow model

View File

@@ -15,9 +15,10 @@ models
| 14 | Summary: repo::test; crate::get_var_field; Argument[0].Field[crate::MyFieldEnum::C::field_c]; ReturnValue; value |
| 15 | Summary: repo::test; crate::get_var_pos; Argument[0].Field[crate::MyPosEnum::A(0)]; ReturnValue; value |
| 16 | Summary: repo::test; crate::set_array_element; Argument[0]; ReturnValue.Element; value |
| 17 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value |
| 18 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Field[crate::MyFieldEnum::D::field_d]; value |
| 19 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Field[crate::MyPosEnum::B(0)]; value |
| 17 | Summary: repo::test; crate::set_struct_field; Argument[0]; ReturnValue.Field[crate::MyStruct::field2]; value |
| 18 | Summary: repo::test; crate::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value |
| 19 | Summary: repo::test; crate::set_var_field; Argument[0]; ReturnValue.Field[crate::MyFieldEnum::D::field_d]; value |
| 20 | Summary: repo::test; crate::set_var_pos; Argument[0]; ReturnValue.Field[crate::MyPosEnum::B(0)]; value |
edges
| main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | |
| main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | |
@@ -48,8 +49,8 @@ edges
| main.rs:54:9:54:10 | e1 [B] | main.rs:55:11:55:12 | e1 [B] | provenance | |
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | |
| main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:19 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:19 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:20 |
| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:20 |
| main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
| main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | |
| main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | |
@@ -76,8 +77,8 @@ edges
| main.rs:86:9:86:10 | e1 [D] | main.rs:87:11:87:12 | e1 [D] | provenance | |
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | |
| main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:18 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:18 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:19 |
| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:19 |
| main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
| main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | |
| main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | |
@@ -96,6 +97,18 @@ edges
| main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:12 |
| main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | |
| main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | |
| main.rs:126:13:126:21 | source(...) | main.rs:126:9:126:9 | s | provenance | |
| main.rs:126:13:126:21 | source(...) | main.rs:126:9:126:9 | s | provenance | |
| main.rs:127:9:127:17 | my_struct [MyStruct.field2] | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | provenance | |
| main.rs:127:9:127:17 | my_struct [MyStruct.field2] | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | provenance | |
| main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | |
| main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | |
| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:17 |
| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:17 |
| main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | |
| main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | |
| main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | |
| main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | |
| main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | |
@@ -136,8 +149,8 @@ edges
| main.rs:173:9:173:9 | t [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | |
| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | |
| main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:17 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:17 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:18 |
| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:18 |
| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | |
| main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | |
| main.rs:184:9:184:9 | s | main.rs:189:11:189:11 | s | provenance | |
@@ -337,6 +350,20 @@ nodes
| main.rs:109:10:109:36 | get_struct_field(...) | semmle.label | get_struct_field(...) |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | semmle.label | my_struct [MyStruct.field1] |
| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | semmle.label | my_struct [MyStruct.field1] |
| main.rs:126:9:126:9 | s | semmle.label | s |
| main.rs:126:9:126:9 | s | semmle.label | s |
| main.rs:126:13:126:21 | source(...) | semmle.label | source(...) |
| main.rs:126:13:126:21 | source(...) | semmle.label | source(...) |
| main.rs:127:9:127:17 | my_struct [MyStruct.field2] | semmle.label | my_struct [MyStruct.field2] |
| main.rs:127:9:127:17 | my_struct [MyStruct.field2] | semmle.label | my_struct [MyStruct.field2] |
| main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | semmle.label | set_struct_field(...) [MyStruct.field2] |
| main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | semmle.label | set_struct_field(...) [MyStruct.field2] |
| main.rs:127:38:127:38 | s | semmle.label | s |
| main.rs:127:38:127:38 | s | semmle.label | s |
| main.rs:129:10:129:18 | my_struct [MyStruct.field2] | semmle.label | my_struct [MyStruct.field2] |
| main.rs:129:10:129:18 | my_struct [MyStruct.field2] | semmle.label | my_struct [MyStruct.field2] |
| main.rs:129:10:129:25 | my_struct.field2 | semmle.label | my_struct.field2 |
| main.rs:129:10:129:25 | my_struct.field2 | semmle.label | my_struct.field2 |
| main.rs:138:9:138:9 | s | semmle.label | s |
| main.rs:138:9:138:9 | s | semmle.label | s |
| main.rs:138:13:138:21 | source(...) | semmle.label | source(...) |
@@ -532,6 +559,8 @@ invalidSpecComponent
| main.rs:89:47:89:47 | i | main.rs:85:13:85:21 | source(...) | main.rs:89:47:89:47 | i | $@ | main.rs:85:13:85:21 | source(...) | source(...) |
| main.rs:109:10:109:36 | get_struct_field(...) | main.rs:104:13:104:21 | source(...) | main.rs:109:10:109:36 | get_struct_field(...) | $@ | main.rs:104:13:104:21 | source(...) | source(...) |
| main.rs:109:10:109:36 | get_struct_field(...) | main.rs:104:13:104:21 | source(...) | main.rs:109:10:109:36 | get_struct_field(...) | $@ | main.rs:104:13:104:21 | source(...) | source(...) |
| main.rs:129:10:129:25 | my_struct.field2 | main.rs:126:13:126:21 | source(...) | main.rs:129:10:129:25 | my_struct.field2 | $@ | main.rs:126:13:126:21 | source(...) | source(...) |
| main.rs:129:10:129:25 | my_struct.field2 | main.rs:126:13:126:21 | source(...) | main.rs:129:10:129:25 | my_struct.field2 | $@ | main.rs:126:13:126:21 | source(...) | source(...) |
| main.rs:139:10:139:31 | get_array_element(...) | main.rs:138:13:138:21 | source(...) | main.rs:139:10:139:31 | get_array_element(...) | $@ | main.rs:138:13:138:21 | source(...) | source(...) |
| main.rs:139:10:139:31 | get_array_element(...) | main.rs:138:13:138:21 | source(...) | main.rs:139:10:139:31 | get_array_element(...) | $@ | main.rs:138:13:138:21 | source(...) | source(...) |
| main.rs:150:10:150:15 | arr[0] | main.rs:148:13:148:21 | source(...) | main.rs:150:10:150:15 | arr[0] | $@ | main.rs:148:13:148:21 | source(...) | source(...) |

View File

@@ -1,3 +0,0 @@
multiplePathResolutions
| main.rs:118:9:118:9 | f | main.rs:104:5:106:5 | fn f |
| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f |

View File

@@ -0,0 +1,6 @@
multiplePathResolutions
| main.rs:118:9:118:9 | f | main.rs:104:5:106:5 | fn f |
| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f |
multipleStaticCallTargets
| main.rs:118:9:118:11 | f(...) | main.rs:104:5:106:5 | fn f |
| main.rs:118:9:118:11 | f(...) | main.rs:110:5:112:5 | fn f |

View File

@@ -184,11 +184,11 @@ mod m8 {
> // $ MISSING: item=52
::f(&x); // $ MISSING: item=I53
let x = MyStruct {}; // $ item=I50
x.f(); // $ MISSING: item=I53
x.f(); // $ item=I53
let x = MyStruct {}; // $ item=I50
x.g(); // $ MISSING: item=I54
x.g(); // $ item=I54
MyStruct::h(&x); // $ item=I74
x.h(); // $ MISSING: item=I74
x.h(); // $ item=I74
} // I55
} // I46
@@ -304,7 +304,7 @@ mod m15 {
fn f(&self) {
println!("m15::Trait2::f");
Self::g(self); // $ item=I80
self.g(); // $ MISSING: item=I80
self.g(); // $ item=I80
}
} // I82
@@ -316,7 +316,7 @@ mod m15 {
fn f(&self) {
println!("m15::<S as Trait1>::f");
Self::g(self); // $ item=I77
self.g(); // $ MISSING: item=I77
self.g(); // $ item=I77
} // I76
fn g(&self) {
@@ -343,7 +343,7 @@ mod m15 {
as Trait2 // $ item=I82
>::f(&x); // $ MISSING: item=I78
S::g(&x); // $ item=I77
x.g(); // $ MISSING: item=I77
x.g(); // $ item=I77
} // I75
}
@@ -359,7 +359,7 @@ mod m16 {
fn h(&self) -> T { // $ item=I84
Self::g(&self); // $ item=I85
self.g() // $ MISSING: item=I85
self.g() // $ item=I85
} // I96
const c: T // $ item=I84
@@ -376,7 +376,7 @@ mod m16 {
fn f(&self) -> T { // $ item=I87
println!("m16::Trait2::f");
Self::g(self); // $ item=I85
self.g(); // $ MISSING: item=I85
self.g(); // $ item=I85
Self::c // $ item=I94
}
} // I89
@@ -391,7 +391,7 @@ mod m16 {
fn f(&self) -> S { // $ item=I90
println!("m16::<S as Trait1<S>>::f");
Self::g(self); // $ item=I92
self.g() // $ MISSING: item=I92
self.g() // $ item=I92
} // I91
fn g(&self) -> S { // $ item=I90
@@ -429,9 +429,9 @@ mod m16 {
> // $ item=I89
>::f(&x); // $ MISSING: item=I93
S::g(&x); // $ item=I92
x.g(); // $ MISSING: item=I92
x.g(); // $ item=I92
S::h(&x); // $ item=I96
x.h(); // $ MISSING: item=I96
x.h(); // $ item=I96
S::c; // $ item=I95
<S // $ item=I90
as Trait1<
@@ -460,7 +460,7 @@ mod m17 {
fn g<T: // I5
MyTrait // $ item=I2
>(x: T) { // $ item=I5
x.f(); // $ MISSING: item=I1
x.f(); // $ item=I1
T::f(&x); // $ item=I1
MyTrait::f(&x); // $ item=I1
} // I6

View File

@@ -1,5 +1,6 @@
import rust
import codeql.rust.elements.internal.PathResolution
import codeql.rust.internal.PathResolution
import codeql.rust.internal.TypeInference
import utils.test.InlineExpectationsTest
import TestUtils
@@ -32,12 +33,15 @@ module ResolveTest implements TestSig {
}
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Path p |
not p = any(Path parent).getQualifier() and
location = p.getLocation() and
element = p.toString() and
item(resolvePath(p), value) and
exists(AstNode n |
not n = any(Path parent).getQualifier() and
location = n.getLocation() and
element = n.toString() and
tag = "item"
|
item(resolvePath(n), value)
or
item(n.(MethodCallExpr).getStaticTarget(), value)
)
}
}

View File

@@ -0,0 +1,574 @@
mod m1 {
pub struct Foo {}
impl Foo {
pub fn m1(self) -> Self {
self
}
pub fn m2(self) -> Foo {
self
}
}
pub fn f() -> Foo {
println!("main.rs::m1::f");
let x = Foo {};
let y: _ = Foo {};
x
}
pub fn g(x: Foo, y: Foo) -> Foo {
println!("main.rs::m1::g");
x.m1();
y.m2()
}
}
mod m2 {
#[derive(Debug)]
struct MyThing<A> {
a: A,
}
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
impl MyThing<S1> {
fn m1(self) -> S1 {
self.a
}
}
impl MyThing<S2> {
fn m1(self) -> Self {
Self { a: self.a }
}
}
impl<T> MyThing<T> {
fn m2(self) -> T {
self.a
}
}
pub fn f() {
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m1()); // missing call target
println!("{:?}", y.m1().a); // missing call target
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m2());
println!("{:?}", y.m2());
}
}
mod m3 {
#[derive(Debug)]
struct MyThing<A> {
a: A,
}
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
trait MyTrait<A> {
fn m1(self) -> A;
fn m2(self) -> Self
where
Self: Sized,
{
self
}
}
fn call_trait_m1<T1, T2: MyTrait<T1>>(x: T2) -> T1 {
x.m1()
}
impl MyTrait<S1> for MyThing<S1> {
fn m1(self) -> S1 {
self.a
}
}
impl MyTrait<Self> for MyThing<S2> {
fn m1(self) -> Self {
Self { a: self.a }
}
}
pub fn f() {
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m1()); // missing call target
println!("{:?}", y.m1().a); // missing call target
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", call_trait_m1(x)); // missing
println!("{:?}", call_trait_m1(y).a); // missing
}
}
mod m4 {
#[derive(Debug)]
struct MyThing<A> {
a: A,
}
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
trait MyTrait<A> {
fn m1(self) -> A;
fn m2(self) -> A
where
Self: Sized,
{
self.m1()
}
}
fn call_trait_m1<T1, T2: MyTrait<T1>>(x: T2) -> T1 {
x.m1()
}
impl<T> MyTrait<T> for MyThing<T> {
fn m1(self) -> T {
self.a
}
}
pub fn f() {
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m1());
println!("{:?}", y.m1());
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m2());
println!("{:?}", y.m2());
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", call_trait_m1(x)); // missing
println!("{:?}", call_trait_m1(y)); // missing
}
}
mod m5 {
trait MyTrait {
type AssociatedType;
fn m1(self) -> Self::AssociatedType;
fn m2(self) -> Self::AssociatedType
where
Self::AssociatedType: Default,
Self: Sized,
{
Self::AssociatedType::default()
}
}
#[derive(Debug, Default)]
struct S;
impl MyTrait for S {
type AssociatedType = S;
fn m1(self) -> Self::AssociatedType {
S
}
}
pub fn f() {
let x = S;
println!("{:?}", x.m1());
let x = S;
println!("{:?}", x.m2()); // missing
}
}
mod m6 {
#[derive(Debug)]
enum MyEnum<A> {
C1(A),
C2 { a: A },
}
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
impl<T> MyEnum<T> {
fn m1(self) -> T {
match self {
MyEnum::C1(a) => a, // missing
MyEnum::C2 { a } => a, // missing
}
}
}
pub fn f() {
let x = MyEnum::C1(S1);
let y = MyEnum::C2 { a: S2 };
println!("{:?}", x.m1());
println!("{:?}", y.m1());
}
}
mod m7 {
#[derive(Debug)]
struct MyThing<A> {
a: A,
}
#[derive(Debug)]
struct MyThing2<A> {
a: A,
}
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
trait MyTrait1<A> {
fn m1(self) -> A;
}
trait MyTrait2<A>: MyTrait1<A> {
fn m2(self) -> A
where
Self: Sized,
{
if 1 + 1 > 2 {
self.m1()
} else {
Self::m1(self)
}
}
}
trait MyTrait3<A>: MyTrait2<MyThing<A>> {
fn m3(self) -> A
where
Self: Sized,
{
if 1 + 1 > 2 {
self.m2().a
} else {
Self::m2(self).a
}
}
}
impl<T> MyTrait1<T> for MyThing<T> {
fn m1(self) -> T {
self.a
}
}
impl<T> MyTrait2<T> for MyThing<T> {}
impl<T> MyTrait1<MyThing<T>> for MyThing2<T> {
fn m1(self) -> MyThing<T> {
MyThing { a: self.a }
}
}
impl<T> MyTrait2<MyThing<T>> for MyThing2<T> {}
impl<T> MyTrait3<T> for MyThing2<T> {}
pub fn f() {
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m1());
println!("{:?}", y.m1());
let x = MyThing { a: S1 };
let y = MyThing { a: S2 };
println!("{:?}", x.m2());
println!("{:?}", y.m2());
let x = MyThing2 { a: S1 };
let y = MyThing2 { a: S2 };
println!("{:?}", x.m3());
println!("{:?}", y.m3());
}
}
mod m8 {
use std::convert::From;
use std::fmt::Debug;
#[derive(Debug)]
struct S1;
#[derive(Debug)]
struct S2;
trait Trait: Debug {}
impl Trait for S1 {}
fn id<T: ?Sized>(x: &T) -> &T {
x
}
impl Into<S2> for S1 {
fn into(self) -> S2 {
S2
}
}
fn into<T1, T2>(x: T1) -> T2
where
T1: Into<T2>,
{
x.into()
}
pub fn f() {
let x = S1;
println!("{:?}", id(&x));
let x = S1;
println!("{:?}", id::<S1>(&x));
let x = S1;
println!("{:?}", id::<dyn Trait>(&x)); // incorrectly has type `S1` instead of `Trait`
let x = S1;
into::<S1, S2>(x);
let x = S1;
let y: S2 = into(x);
}
}
mod m9 {
#[derive(Debug)]
enum MyOption<T> {
MyNone(),
MySome(T),
}
trait MyTrait<S> {
fn set(&mut self, value: S);
fn call_set(&mut self, value: S) {
self.set(value);
}
}
impl<T> MyTrait<T> for MyOption<T> {
fn set(&mut self, value: T) {}
}
impl<T> MyOption<T> {
fn new() -> Self {
MyOption::MyNone()
}
}
impl<T> MyOption<MyOption<T>> {
fn flatten(self) -> MyOption<T> {
match self {
MyOption::MyNone() => MyOption::MyNone(), // missing inner type `Option<T>`
MyOption::MySome(x) => x, // missing
}
}
}
#[derive(Debug)]
struct S;
pub fn f() {
let x1 = MyOption::<S>::new(); // `::new` missing type `S`
println!("{:?}", x1);
let mut x2 = MyOption::new();
x2.set(S);
println!("{:?}", x2);
let mut x3 = MyOption::new(); // missing type `S` from `MyOption<S>` (but can resolve `MyTrait<S>`)
x3.call_set(S);
println!("{:?}", x3);
let mut x4 = MyOption::new();
MyOption::set(&mut x4, S);
println!("{:?}", x4);
let x5 = MyOption::MySome(MyOption::<S>::MyNone());
println!("{:?}", x5.flatten()); // missing call target
let x6 = MyOption::MySome(MyOption::<S>::MyNone());
println!("{:?}", MyOption::<MyOption<S>>::flatten(x6));
}
}
mod m10 {
#[derive(Debug, Copy, Clone)]
struct S<T>(T);
#[derive(Debug, Copy, Clone)]
struct S2;
impl<T> S<T> {
fn m1(self) -> T {
self.0
}
fn m2(&self) -> &T {
&self.0
}
fn m3(self: &S<T>) -> &T {
&self.0
}
}
pub fn f() {
let x1 = S(S2);
println!("{:?}", x1.m1());
let x2 = S(S2);
// implicit borrow
println!("{:?}", x2.m2());
println!("{:?}", x2.m3());
let x3 = S(S2);
// explicit borrow
println!("{:?}", S::<S2>::m2(&x3));
println!("{:?}", S::<S2>::m3(&x3));
let x4 = &S(S2);
// explicit borrow
println!("{:?}", x4.m2());
println!("{:?}", x4.m3());
let x5 = &S(S2);
// implicit dereference
println!("{:?}", x5.m1());
println!("{:?}", x5.0);
let x6 = &S(S2);
// explicit dereference
println!("{:?}", (*x6).m1());
}
}
mod m11 {
trait MyTrait {
fn foo(&self) -> &Self;
fn bar(&self) -> &Self {
self.foo()
}
}
struct MyStruct;
impl MyTrait for MyStruct {
fn foo(&self) -> &MyStruct {
self
}
}
pub fn f() {
let x = MyStruct;
x.bar();
}
}
mod m12 {
struct S;
struct MyStruct<T>(T);
impl<T> MyStruct<T> {
fn foo(&self) -> &Self {
self
}
}
pub fn f() {
let x = MyStruct(S);
x.foo();
}
}
mod m13 {
struct S;
impl S {
fn f1(&self) -> &Self {
&&&self
}
fn f2(self: &Self) -> &Self {
&&&self
}
fn f3(x: &Self) -> &Self {
x
}
fn f4(x: &Self) -> &Self {
&&&x
}
}
pub fn f() {
let x = S {};
x.f1();
x.f2();
S::f3(&x);
}
}
fn main() {
m1::f();
m1::g(m1::Foo {}, m1::Foo {});
m2::f();
m3::f();
m4::f();
m5::f();
m6::f();
m7::f();
m8::f();
m9::f();
m10::f();
m11::f();
m12::f();
m13::f();
}

View File

@@ -0,0 +1,792 @@
inferType
| main.rs:5:19:5:22 | SelfParam | | main.rs:2:5:2:21 | struct Foo |
| main.rs:5:33:7:9 | { ... } | | main.rs:2:5:2:21 | struct Foo |
| main.rs:6:13:6:16 | self | | main.rs:2:5:2:21 | struct Foo |
| main.rs:9:19:9:22 | SelfParam | | main.rs:2:5:2:21 | struct Foo |
| main.rs:9:32:11:9 | { ... } | | main.rs:2:5:2:21 | struct Foo |
| main.rs:10:13:10:16 | self | | main.rs:2:5:2:21 | struct Foo |
| main.rs:14:23:19:5 | { ... } | | main.rs:2:5:2:21 | struct Foo |
| main.rs:16:13:16:13 | x | | main.rs:2:5:2:21 | struct Foo |
| main.rs:16:17:16:22 | Foo {...} | | main.rs:2:5:2:21 | struct Foo |
| main.rs:17:13:17:13 | y | | main.rs:2:5:2:21 | struct Foo |
| main.rs:17:20:17:25 | Foo {...} | | main.rs:2:5:2:21 | struct Foo |
| main.rs:18:9:18:9 | x | | main.rs:2:5:2:21 | struct Foo |
| main.rs:21:14:21:14 | x | | main.rs:2:5:2:21 | struct Foo |
| main.rs:21:22:21:22 | y | | main.rs:2:5:2:21 | struct Foo |
| main.rs:21:37:25:5 | { ... } | | main.rs:2:5:2:21 | struct Foo |
| main.rs:23:9:23:9 | x | | main.rs:2:5:2:21 | struct Foo |
| main.rs:23:9:23:14 | x.m1(...) | | main.rs:2:5:2:21 | struct Foo |
| main.rs:24:9:24:9 | y | | main.rs:2:5:2:21 | struct Foo |
| main.rs:24:9:24:14 | y.m2(...) | | main.rs:2:5:2:21 | struct Foo |
| main.rs:40:15:40:18 | SelfParam | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:40:15:40:18 | SelfParam | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:40:27:42:9 | { ... } | | main.rs:34:5:35:14 | struct S1 |
| main.rs:41:13:41:16 | self | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:41:13:41:16 | self | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:41:13:41:18 | self.a | | main.rs:34:5:35:14 | struct S1 |
| main.rs:46:15:46:18 | SelfParam | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:46:15:46:18 | SelfParam | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:46:29:48:9 | { ... } | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:46:29:48:9 | { ... } | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:47:13:47:30 | Self {...} | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:47:13:47:30 | Self {...} | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:47:23:47:26 | self | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:47:23:47:26 | self | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:47:23:47:28 | self.a | | main.rs:36:5:37:14 | struct S2 |
| main.rs:52:15:52:18 | SelfParam | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:52:15:52:18 | SelfParam | A | main.rs:51:10:51:10 | T |
| main.rs:52:26:54:9 | { ... } | | main.rs:51:10:51:10 | T |
| main.rs:53:13:53:16 | self | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:53:13:53:16 | self | A | main.rs:51:10:51:10 | T |
| main.rs:53:13:53:18 | self.a | | main.rs:51:10:51:10 | T |
| main.rs:58:13:58:13 | x | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:58:13:58:13 | x | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:58:17:58:33 | MyThing {...} | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:58:17:58:33 | MyThing {...} | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:58:30:58:31 | S1 | | main.rs:34:5:35:14 | struct S1 |
| main.rs:59:13:59:13 | y | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:59:13:59:13 | y | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:59:17:59:33 | MyThing {...} | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:59:17:59:33 | MyThing {...} | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:59:30:59:31 | S2 | | main.rs:36:5:37:14 | struct S2 |
| main.rs:61:26:61:26 | x | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:61:26:61:26 | x | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:62:26:62:26 | y | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:62:26:62:26 | y | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:64:13:64:13 | x | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:64:13:64:13 | x | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:64:17:64:33 | MyThing {...} | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:64:17:64:33 | MyThing {...} | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:64:30:64:31 | S1 | | main.rs:34:5:35:14 | struct S1 |
| main.rs:65:13:65:13 | y | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:65:13:65:13 | y | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:65:17:65:33 | MyThing {...} | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:65:17:65:33 | MyThing {...} | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:65:30:65:31 | S2 | | main.rs:36:5:37:14 | struct S2 |
| main.rs:67:26:67:26 | x | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:67:26:67:26 | x | A | main.rs:34:5:35:14 | struct S1 |
| main.rs:67:26:67:31 | x.m2(...) | | main.rs:34:5:35:14 | struct S1 |
| main.rs:68:26:68:26 | y | | main.rs:29:5:32:5 | struct MyThing |
| main.rs:68:26:68:26 | y | A | main.rs:36:5:37:14 | struct S2 |
| main.rs:68:26:68:31 | y.m2(...) | | main.rs:36:5:37:14 | struct S2 |
| main.rs:84:15:84:18 | SelfParam | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:84:15:84:18 | SelfParam | A | main.rs:83:19:83:19 | A |
| main.rs:86:15:86:18 | SelfParam | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:86:15:86:18 | SelfParam | A | main.rs:83:19:83:19 | A |
| main.rs:89:9:91:9 | { ... } | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:89:9:91:9 | { ... } | A | main.rs:83:19:83:19 | A |
| main.rs:90:13:90:16 | self | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:90:13:90:16 | self | A | main.rs:83:19:83:19 | A |
| main.rs:94:43:94:43 | x | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:94:43:94:43 | x | | main.rs:94:26:94:40 | T2 |
| main.rs:94:43:94:43 | x | A | main.rs:94:22:94:23 | T1 |
| main.rs:94:56:96:5 | { ... } | | main.rs:94:22:94:23 | T1 |
| main.rs:95:9:95:9 | x | | main.rs:83:5:92:5 | trait MyTrait |
| main.rs:95:9:95:9 | x | | main.rs:94:26:94:40 | T2 |
| main.rs:95:9:95:9 | x | A | main.rs:94:22:94:23 | T1 |
| main.rs:95:9:95:14 | x.m1(...) | | main.rs:94:22:94:23 | T1 |
| main.rs:99:15:99:18 | SelfParam | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:99:15:99:18 | SelfParam | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:99:27:101:9 | { ... } | | main.rs:78:5:79:14 | struct S1 |
| main.rs:100:13:100:16 | self | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:100:13:100:16 | self | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:100:13:100:18 | self.a | | main.rs:78:5:79:14 | struct S1 |
| main.rs:105:15:105:18 | SelfParam | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:105:15:105:18 | SelfParam | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:105:29:107:9 | { ... } | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:105:29:107:9 | { ... } | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:106:13:106:30 | Self {...} | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:106:13:106:30 | Self {...} | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:106:23:106:26 | self | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:106:23:106:26 | self | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:106:23:106:28 | self.a | | main.rs:80:5:81:14 | struct S2 |
| main.rs:111:13:111:13 | x | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:111:13:111:13 | x | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:111:17:111:33 | MyThing {...} | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:111:17:111:33 | MyThing {...} | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:111:30:111:31 | S1 | | main.rs:78:5:79:14 | struct S1 |
| main.rs:112:13:112:13 | y | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:112:13:112:13 | y | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:112:17:112:33 | MyThing {...} | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:112:17:112:33 | MyThing {...} | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:112:30:112:31 | S2 | | main.rs:80:5:81:14 | struct S2 |
| main.rs:114:26:114:26 | x | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:114:26:114:26 | x | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:115:26:115:26 | y | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:115:26:115:26 | y | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:117:13:117:13 | x | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:117:13:117:13 | x | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:117:17:117:33 | MyThing {...} | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:117:17:117:33 | MyThing {...} | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:117:30:117:31 | S1 | | main.rs:78:5:79:14 | struct S1 |
| main.rs:118:13:118:13 | y | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:118:13:118:13 | y | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:118:17:118:33 | MyThing {...} | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:118:17:118:33 | MyThing {...} | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:118:30:118:31 | S2 | | main.rs:80:5:81:14 | struct S2 |
| main.rs:120:40:120:40 | x | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:120:40:120:40 | x | A | main.rs:78:5:79:14 | struct S1 |
| main.rs:121:40:121:40 | y | | main.rs:73:5:76:5 | struct MyThing |
| main.rs:121:40:121:40 | y | A | main.rs:80:5:81:14 | struct S2 |
| main.rs:137:15:137:18 | SelfParam | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:137:15:137:18 | SelfParam | A | main.rs:136:19:136:19 | A |
| main.rs:139:15:139:18 | SelfParam | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:139:15:139:18 | SelfParam | A | main.rs:136:19:136:19 | A |
| main.rs:142:9:144:9 | { ... } | | main.rs:136:19:136:19 | A |
| main.rs:143:13:143:16 | self | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:143:13:143:16 | self | A | main.rs:136:19:136:19 | A |
| main.rs:143:13:143:21 | self.m1(...) | | main.rs:136:19:136:19 | A |
| main.rs:147:43:147:43 | x | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:147:43:147:43 | x | | main.rs:147:26:147:40 | T2 |
| main.rs:147:43:147:43 | x | A | main.rs:147:22:147:23 | T1 |
| main.rs:147:56:149:5 | { ... } | | main.rs:147:22:147:23 | T1 |
| main.rs:148:9:148:9 | x | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:148:9:148:9 | x | | main.rs:147:26:147:40 | T2 |
| main.rs:148:9:148:9 | x | A | main.rs:147:22:147:23 | T1 |
| main.rs:148:9:148:14 | x.m1(...) | | main.rs:147:22:147:23 | T1 |
| main.rs:152:15:152:18 | SelfParam | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:152:15:152:18 | SelfParam | A | main.rs:151:10:151:10 | T |
| main.rs:152:26:154:9 | { ... } | | main.rs:151:10:151:10 | T |
| main.rs:153:13:153:16 | self | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:153:13:153:16 | self | A | main.rs:151:10:151:10 | T |
| main.rs:153:13:153:18 | self.a | | main.rs:151:10:151:10 | T |
| main.rs:158:13:158:13 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:158:13:158:13 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:158:17:158:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:158:17:158:33 | MyThing {...} | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:158:30:158:31 | S1 | | main.rs:131:5:132:14 | struct S1 |
| main.rs:159:13:159:13 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:159:13:159:13 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:159:17:159:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:159:17:159:33 | MyThing {...} | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:159:30:159:31 | S2 | | main.rs:133:5:134:14 | struct S2 |
| main.rs:161:26:161:26 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:161:26:161:26 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:161:26:161:31 | x.m1(...) | | main.rs:131:5:132:14 | struct S1 |
| main.rs:162:26:162:26 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:162:26:162:26 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:162:26:162:31 | y.m1(...) | | main.rs:133:5:134:14 | struct S2 |
| main.rs:164:13:164:13 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:164:13:164:13 | x | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:164:13:164:13 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:164:13:164:13 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:164:17:164:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:164:17:164:33 | MyThing {...} | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:164:17:164:33 | MyThing {...} | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:164:17:164:33 | MyThing {...} | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:164:30:164:31 | S1 | | main.rs:131:5:132:14 | struct S1 |
| main.rs:165:13:165:13 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:165:13:165:13 | y | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:165:13:165:13 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:165:13:165:13 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:165:17:165:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:165:17:165:33 | MyThing {...} | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:165:17:165:33 | MyThing {...} | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:165:17:165:33 | MyThing {...} | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:165:30:165:31 | S2 | | main.rs:133:5:134:14 | struct S2 |
| main.rs:167:26:167:26 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:167:26:167:26 | x | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:167:26:167:26 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:167:26:167:26 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:167:26:167:31 | x.m2(...) | | main.rs:131:5:132:14 | struct S1 |
| main.rs:168:26:168:26 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:168:26:168:26 | y | | main.rs:136:5:145:5 | trait MyTrait |
| main.rs:168:26:168:26 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:168:26:168:26 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:168:26:168:31 | y.m2(...) | | main.rs:133:5:134:14 | struct S2 |
| main.rs:170:13:170:13 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:170:13:170:13 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:170:17:170:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:170:17:170:33 | MyThing {...} | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:170:30:170:31 | S1 | | main.rs:131:5:132:14 | struct S1 |
| main.rs:171:13:171:13 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:171:13:171:13 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:171:17:171:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:171:17:171:33 | MyThing {...} | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:171:30:171:31 | S2 | | main.rs:133:5:134:14 | struct S2 |
| main.rs:173:40:173:40 | x | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:173:40:173:40 | x | A | main.rs:131:5:132:14 | struct S1 |
| main.rs:174:40:174:40 | y | | main.rs:126:5:129:5 | struct MyThing |
| main.rs:174:40:174:40 | y | A | main.rs:133:5:134:14 | struct S2 |
| main.rs:182:15:182:18 | SelfParam | | main.rs:179:5:191:5 | trait MyTrait |
| main.rs:184:15:184:18 | SelfParam | | main.rs:179:5:191:5 | trait MyTrait |
| main.rs:199:15:199:18 | SelfParam | | main.rs:193:5:194:13 | struct S |
| main.rs:199:45:201:9 | { ... } | | main.rs:193:5:194:13 | struct S |
| main.rs:200:13:200:13 | S | | main.rs:193:5:194:13 | struct S |
| main.rs:205:13:205:13 | x | | main.rs:193:5:194:13 | struct S |
| main.rs:205:17:205:17 | S | | main.rs:193:5:194:13 | struct S |
| main.rs:206:26:206:26 | x | | main.rs:193:5:194:13 | struct S |
| main.rs:206:26:206:31 | x.m1(...) | | main.rs:193:5:194:13 | struct S |
| main.rs:208:13:208:13 | x | | main.rs:179:5:191:5 | trait MyTrait |
| main.rs:208:13:208:13 | x | | main.rs:193:5:194:13 | struct S |
| main.rs:208:17:208:17 | S | | main.rs:179:5:191:5 | trait MyTrait |
| main.rs:208:17:208:17 | S | | main.rs:193:5:194:13 | struct S |
| main.rs:209:26:209:26 | x | | main.rs:179:5:191:5 | trait MyTrait |
| main.rs:209:26:209:26 | x | | main.rs:193:5:194:13 | struct S |
| main.rs:226:15:226:18 | SelfParam | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:226:15:226:18 | SelfParam | A | main.rs:225:10:225:10 | T |
| main.rs:226:26:231:9 | { ... } | | main.rs:225:10:225:10 | T |
| main.rs:227:13:230:13 | match self { ... } | | main.rs:225:10:225:10 | T |
| main.rs:227:19:227:22 | self | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:227:19:227:22 | self | A | main.rs:225:10:225:10 | T |
| main.rs:235:13:235:13 | x | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:235:13:235:13 | x | A | main.rs:220:5:221:14 | struct S1 |
| main.rs:235:17:235:30 | ...::C1(...) | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:235:17:235:30 | ...::C1(...) | A | main.rs:220:5:221:14 | struct S1 |
| main.rs:235:28:235:29 | S1 | | main.rs:220:5:221:14 | struct S1 |
| main.rs:236:13:236:13 | y | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:236:13:236:13 | y | A | main.rs:222:5:223:14 | struct S2 |
| main.rs:236:17:236:36 | ...::C2 {...} | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:236:17:236:36 | ...::C2 {...} | A | main.rs:222:5:223:14 | struct S2 |
| main.rs:236:33:236:34 | S2 | | main.rs:222:5:223:14 | struct S2 |
| main.rs:238:26:238:26 | x | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:238:26:238:26 | x | A | main.rs:220:5:221:14 | struct S1 |
| main.rs:238:26:238:31 | x.m1(...) | | main.rs:220:5:221:14 | struct S1 |
| main.rs:239:26:239:26 | y | | main.rs:214:5:218:5 | enum MyEnum |
| main.rs:239:26:239:26 | y | A | main.rs:222:5:223:14 | struct S2 |
| main.rs:239:26:239:31 | y.m1(...) | | main.rs:222:5:223:14 | struct S2 |
| main.rs:260:15:260:18 | SelfParam | | main.rs:259:5:261:5 | trait MyTrait1 |
| main.rs:260:15:260:18 | SelfParam | A | main.rs:259:20:259:20 | A |
| main.rs:264:15:264:18 | SelfParam | | main.rs:259:5:261:5 | trait MyTrait1 |
| main.rs:264:15:264:18 | SelfParam | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:264:15:264:18 | SelfParam | A | main.rs:263:20:263:20 | A |
| main.rs:264:15:264:18 | SelfParam | A | main.rs:263:20:263:20 | A |
| main.rs:267:9:273:9 | { ... } | | main.rs:263:20:263:20 | A |
| main.rs:268:13:272:13 | if ... {...} else {...} | | main.rs:263:20:263:20 | A |
| main.rs:268:26:270:13 | { ... } | | main.rs:263:20:263:20 | A |
| main.rs:269:17:269:20 | self | | main.rs:259:5:261:5 | trait MyTrait1 |
| main.rs:269:17:269:20 | self | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:269:17:269:20 | self | A | main.rs:263:20:263:20 | A |
| main.rs:269:17:269:20 | self | A | main.rs:263:20:263:20 | A |
| main.rs:269:17:269:25 | self.m1(...) | | main.rs:263:20:263:20 | A |
| main.rs:270:20:272:13 | { ... } | | main.rs:263:20:263:20 | A |
| main.rs:271:17:271:30 | ...::m1(...) | | main.rs:263:20:263:20 | A |
| main.rs:271:26:271:29 | self | | main.rs:259:5:261:5 | trait MyTrait1 |
| main.rs:271:26:271:29 | self | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:271:26:271:29 | self | A | main.rs:263:20:263:20 | A |
| main.rs:271:26:271:29 | self | A | main.rs:263:20:263:20 | A |
| main.rs:277:15:277:18 | SelfParam | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:277:15:277:18 | SelfParam | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:277:15:277:18 | SelfParam | A | main.rs:244:5:247:5 | struct MyThing |
| main.rs:277:15:277:18 | SelfParam | A | main.rs:276:20:276:20 | A |
| main.rs:277:15:277:18 | SelfParam | A.A | main.rs:276:20:276:20 | A |
| main.rs:280:9:286:9 | { ... } | | main.rs:276:20:276:20 | A |
| main.rs:281:13:285:13 | if ... {...} else {...} | | main.rs:276:20:276:20 | A |
| main.rs:281:26:283:13 | { ... } | | main.rs:276:20:276:20 | A |
| main.rs:282:17:282:20 | self | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:282:17:282:20 | self | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:282:17:282:20 | self | A | main.rs:244:5:247:5 | struct MyThing |
| main.rs:282:17:282:20 | self | A | main.rs:276:20:276:20 | A |
| main.rs:282:17:282:20 | self | A.A | main.rs:276:20:276:20 | A |
| main.rs:282:17:282:25 | self.m2(...) | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:282:17:282:25 | self.m2(...) | A | main.rs:276:20:276:20 | A |
| main.rs:282:17:282:27 | ... .a | | main.rs:276:20:276:20 | A |
| main.rs:283:20:285:13 | { ... } | | main.rs:276:20:276:20 | A |
| main.rs:284:17:284:30 | ...::m2(...) | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:284:17:284:30 | ...::m2(...) | A | main.rs:276:20:276:20 | A |
| main.rs:284:17:284:32 | ... .a | | main.rs:276:20:276:20 | A |
| main.rs:284:26:284:29 | self | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:284:26:284:29 | self | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:284:26:284:29 | self | A | main.rs:244:5:247:5 | struct MyThing |
| main.rs:284:26:284:29 | self | A | main.rs:276:20:276:20 | A |
| main.rs:284:26:284:29 | self | A.A | main.rs:276:20:276:20 | A |
| main.rs:290:15:290:18 | SelfParam | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:290:15:290:18 | SelfParam | A | main.rs:289:10:289:10 | T |
| main.rs:290:26:292:9 | { ... } | | main.rs:289:10:289:10 | T |
| main.rs:291:13:291:16 | self | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:291:13:291:16 | self | A | main.rs:289:10:289:10 | T |
| main.rs:291:13:291:18 | self.a | | main.rs:289:10:289:10 | T |
| main.rs:298:15:298:18 | SelfParam | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:298:15:298:18 | SelfParam | A | main.rs:297:10:297:10 | T |
| main.rs:298:35:300:9 | { ... } | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:298:35:300:9 | { ... } | A | main.rs:297:10:297:10 | T |
| main.rs:299:13:299:33 | MyThing {...} | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:299:13:299:33 | MyThing {...} | A | main.rs:297:10:297:10 | T |
| main.rs:299:26:299:29 | self | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:299:26:299:29 | self | A | main.rs:297:10:297:10 | T |
| main.rs:299:26:299:31 | self.a | | main.rs:297:10:297:10 | T |
| main.rs:308:13:308:13 | x | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:308:13:308:13 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:308:17:308:33 | MyThing {...} | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:308:17:308:33 | MyThing {...} | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:308:30:308:31 | S1 | | main.rs:254:5:255:14 | struct S1 |
| main.rs:309:13:309:13 | y | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:309:13:309:13 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:309:17:309:33 | MyThing {...} | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:309:17:309:33 | MyThing {...} | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:309:30:309:31 | S2 | | main.rs:256:5:257:14 | struct S2 |
| main.rs:311:26:311:26 | x | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:311:26:311:26 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:311:26:311:31 | x.m1(...) | | main.rs:254:5:255:14 | struct S1 |
| main.rs:312:26:312:26 | y | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:312:26:312:26 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:312:26:312:31 | y.m1(...) | | main.rs:256:5:257:14 | struct S2 |
| main.rs:314:13:314:13 | x | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:314:13:314:13 | x | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:314:13:314:13 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:314:13:314:13 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:314:17:314:33 | MyThing {...} | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:314:17:314:33 | MyThing {...} | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:314:17:314:33 | MyThing {...} | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:314:17:314:33 | MyThing {...} | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:314:30:314:31 | S1 | | main.rs:254:5:255:14 | struct S1 |
| main.rs:315:13:315:13 | y | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:315:13:315:13 | y | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:315:13:315:13 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:315:13:315:13 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:315:17:315:33 | MyThing {...} | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:315:17:315:33 | MyThing {...} | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:315:17:315:33 | MyThing {...} | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:315:17:315:33 | MyThing {...} | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:315:30:315:31 | S2 | | main.rs:256:5:257:14 | struct S2 |
| main.rs:317:26:317:26 | x | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:317:26:317:26 | x | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:317:26:317:26 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:317:26:317:26 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:317:26:317:31 | x.m2(...) | | main.rs:254:5:255:14 | struct S1 |
| main.rs:318:26:318:26 | y | | main.rs:244:5:247:5 | struct MyThing |
| main.rs:318:26:318:26 | y | | main.rs:263:5:274:5 | trait MyTrait2 |
| main.rs:318:26:318:26 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:318:26:318:26 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:318:26:318:31 | y.m2(...) | | main.rs:256:5:257:14 | struct S2 |
| main.rs:320:13:320:13 | x | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:320:13:320:13 | x | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:320:13:320:13 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:320:13:320:13 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:320:17:320:34 | MyThing2 {...} | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:320:17:320:34 | MyThing2 {...} | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:320:17:320:34 | MyThing2 {...} | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:320:17:320:34 | MyThing2 {...} | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:320:31:320:32 | S1 | | main.rs:254:5:255:14 | struct S1 |
| main.rs:321:13:321:13 | y | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:321:13:321:13 | y | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:321:13:321:13 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:321:13:321:13 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:321:17:321:34 | MyThing2 {...} | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:321:17:321:34 | MyThing2 {...} | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:321:17:321:34 | MyThing2 {...} | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:321:17:321:34 | MyThing2 {...} | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:321:31:321:32 | S2 | | main.rs:256:5:257:14 | struct S2 |
| main.rs:323:26:323:26 | x | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:323:26:323:26 | x | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:323:26:323:26 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:323:26:323:26 | x | A | main.rs:254:5:255:14 | struct S1 |
| main.rs:323:26:323:31 | x.m3(...) | | main.rs:254:5:255:14 | struct S1 |
| main.rs:324:26:324:26 | y | | main.rs:249:5:252:5 | struct MyThing2 |
| main.rs:324:26:324:26 | y | | main.rs:276:5:287:5 | trait MyTrait3 |
| main.rs:324:26:324:26 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:324:26:324:26 | y | A | main.rs:256:5:257:14 | struct S2 |
| main.rs:324:26:324:31 | y.m3(...) | | main.rs:256:5:257:14 | struct S2 |
| main.rs:342:22:342:22 | x | | file://:0:0:0:0 | & |
| main.rs:342:22:342:22 | x | &T | main.rs:342:11:342:19 | T |
| main.rs:342:35:344:5 | { ... } | | file://:0:0:0:0 | & |
| main.rs:342:35:344:5 | { ... } | &T | main.rs:342:11:342:19 | T |
| main.rs:343:9:343:9 | x | | file://:0:0:0:0 | & |
| main.rs:343:9:343:9 | x | &T | main.rs:342:11:342:19 | T |
| main.rs:347:17:347:20 | SelfParam | | main.rs:332:5:333:14 | struct S1 |
| main.rs:347:29:349:9 | { ... } | | main.rs:335:5:336:14 | struct S2 |
| main.rs:348:13:348:14 | S2 | | main.rs:335:5:336:14 | struct S2 |
| main.rs:352:21:352:21 | x | | main.rs:352:13:352:14 | T1 |
| main.rs:355:5:357:5 | { ... } | | main.rs:352:17:352:18 | T2 |
| main.rs:356:9:356:9 | x | | main.rs:352:13:352:14 | T1 |
| main.rs:356:9:356:16 | x.into(...) | | main.rs:352:17:352:18 | T2 |
| main.rs:360:13:360:13 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:360:17:360:18 | S1 | | main.rs:332:5:333:14 | struct S1 |
| main.rs:361:26:361:31 | id(...) | | file://:0:0:0:0 | & |
| main.rs:361:26:361:31 | id(...) | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:361:29:361:30 | &x | | file://:0:0:0:0 | & |
| main.rs:361:29:361:30 | &x | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:361:30:361:30 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:363:13:363:13 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:363:17:363:18 | S1 | | main.rs:332:5:333:14 | struct S1 |
| main.rs:364:26:364:37 | id::<...>(...) | | file://:0:0:0:0 | & |
| main.rs:364:26:364:37 | id::<...>(...) | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:364:35:364:36 | &x | | file://:0:0:0:0 | & |
| main.rs:364:35:364:36 | &x | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:364:36:364:36 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:366:13:366:13 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:366:17:366:18 | S1 | | main.rs:332:5:333:14 | struct S1 |
| main.rs:367:26:367:44 | id::<...>(...) | | file://:0:0:0:0 | & |
| main.rs:367:26:367:44 | id::<...>(...) | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:367:42:367:43 | &x | | file://:0:0:0:0 | & |
| main.rs:367:42:367:43 | &x | &T | main.rs:332:5:333:14 | struct S1 |
| main.rs:367:43:367:43 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:369:13:369:13 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:369:17:369:18 | S1 | | main.rs:332:5:333:14 | struct S1 |
| main.rs:370:9:370:25 | into::<...>(...) | | main.rs:335:5:336:14 | struct S2 |
| main.rs:370:24:370:24 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:372:13:372:13 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:372:17:372:18 | S1 | | main.rs:332:5:333:14 | struct S1 |
| main.rs:373:13:373:13 | y | | main.rs:335:5:336:14 | struct S2 |
| main.rs:373:21:373:27 | into(...) | | main.rs:335:5:336:14 | struct S2 |
| main.rs:373:26:373:26 | x | | main.rs:332:5:333:14 | struct S1 |
| main.rs:385:16:385:24 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:385:16:385:24 | SelfParam | &T | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:385:16:385:24 | SelfParam | &T.S | main.rs:384:19:384:19 | S |
| main.rs:385:27:385:31 | value | | main.rs:384:19:384:19 | S |
| main.rs:387:21:387:29 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:387:21:387:29 | SelfParam | &T | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:387:21:387:29 | SelfParam | &T.S | main.rs:384:19:384:19 | S |
| main.rs:387:32:387:36 | value | | main.rs:384:19:384:19 | S |
| main.rs:388:13:388:16 | self | | file://:0:0:0:0 | & |
| main.rs:388:13:388:16 | self | &T | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:388:13:388:16 | self | &T.S | main.rs:384:19:384:19 | S |
| main.rs:388:22:388:26 | value | | main.rs:384:19:384:19 | S |
| main.rs:393:16:393:24 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:393:16:393:24 | SelfParam | &T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:393:16:393:24 | SelfParam | &T.T | main.rs:392:10:392:10 | T |
| main.rs:393:27:393:31 | value | | main.rs:392:10:392:10 | T |
| main.rs:397:26:399:9 | { ... } | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:397:26:399:9 | { ... } | T | main.rs:396:10:396:10 | T |
| main.rs:398:13:398:30 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:398:13:398:30 | ...::MyNone(...) | T | main.rs:396:10:396:10 | T |
| main.rs:403:20:403:23 | SelfParam | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:403:20:403:23 | SelfParam | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:403:20:403:23 | SelfParam | T.T | main.rs:402:10:402:10 | T |
| main.rs:403:41:408:9 | { ... } | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:403:41:408:9 | { ... } | T | main.rs:402:10:402:10 | T |
| main.rs:404:13:407:13 | match self { ... } | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:404:13:407:13 | match self { ... } | T | main.rs:402:10:402:10 | T |
| main.rs:404:19:404:22 | self | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:404:19:404:22 | self | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:404:19:404:22 | self | T.T | main.rs:402:10:402:10 | T |
| main.rs:405:39:405:56 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:415:13:415:14 | x1 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:415:18:415:37 | ...::new(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:416:26:416:27 | x1 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:418:13:418:18 | mut x2 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:418:13:418:18 | mut x2 | T | main.rs:411:5:412:13 | struct S |
| main.rs:418:22:418:36 | ...::new(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:418:22:418:36 | ...::new(...) | T | main.rs:411:5:412:13 | struct S |
| main.rs:419:9:419:10 | x2 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:419:9:419:10 | x2 | T | main.rs:411:5:412:13 | struct S |
| main.rs:419:16:419:16 | S | | main.rs:411:5:412:13 | struct S |
| main.rs:420:26:420:27 | x2 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:420:26:420:27 | x2 | T | main.rs:411:5:412:13 | struct S |
| main.rs:422:13:422:18 | mut x3 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:422:13:422:18 | mut x3 | | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:422:13:422:18 | mut x3 | S | main.rs:411:5:412:13 | struct S |
| main.rs:422:22:422:36 | ...::new(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:422:22:422:36 | ...::new(...) | | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:422:22:422:36 | ...::new(...) | S | main.rs:411:5:412:13 | struct S |
| main.rs:423:9:423:10 | x3 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:423:9:423:10 | x3 | | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:423:9:423:10 | x3 | S | main.rs:411:5:412:13 | struct S |
| main.rs:423:21:423:21 | S | | main.rs:411:5:412:13 | struct S |
| main.rs:424:26:424:27 | x3 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:424:26:424:27 | x3 | | main.rs:384:5:390:5 | trait MyTrait |
| main.rs:424:26:424:27 | x3 | S | main.rs:411:5:412:13 | struct S |
| main.rs:426:13:426:18 | mut x4 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:426:13:426:18 | mut x4 | T | main.rs:411:5:412:13 | struct S |
| main.rs:426:22:426:36 | ...::new(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:426:22:426:36 | ...::new(...) | T | main.rs:411:5:412:13 | struct S |
| main.rs:427:23:427:29 | &mut x4 | | file://:0:0:0:0 | & |
| main.rs:427:23:427:29 | &mut x4 | &T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:427:23:427:29 | &mut x4 | &T.T | main.rs:411:5:412:13 | struct S |
| main.rs:427:28:427:29 | x4 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:427:28:427:29 | x4 | T | main.rs:411:5:412:13 | struct S |
| main.rs:427:32:427:32 | S | | main.rs:411:5:412:13 | struct S |
| main.rs:428:26:428:27 | x4 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:428:26:428:27 | x4 | T | main.rs:411:5:412:13 | struct S |
| main.rs:430:13:430:14 | x5 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:430:13:430:14 | x5 | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:430:13:430:14 | x5 | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:430:18:430:58 | ...::MySome(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:430:18:430:58 | ...::MySome(...) | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:430:18:430:58 | ...::MySome(...) | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:430:35:430:57 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:430:35:430:57 | ...::MyNone(...) | T | main.rs:411:5:412:13 | struct S |
| main.rs:431:26:431:27 | x5 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:431:26:431:27 | x5 | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:431:26:431:27 | x5 | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:433:13:433:14 | x6 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:433:13:433:14 | x6 | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:433:13:433:14 | x6 | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:433:18:433:58 | ...::MySome(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:433:18:433:58 | ...::MySome(...) | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:433:18:433:58 | ...::MySome(...) | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:433:35:433:57 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:433:35:433:57 | ...::MyNone(...) | T | main.rs:411:5:412:13 | struct S |
| main.rs:434:26:434:61 | ...::flatten(...) | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:434:26:434:61 | ...::flatten(...) | T | main.rs:411:5:412:13 | struct S |
| main.rs:434:59:434:60 | x6 | | main.rs:378:5:382:5 | enum MyOption |
| main.rs:434:59:434:60 | x6 | T | main.rs:378:5:382:5 | enum MyOption |
| main.rs:434:59:434:60 | x6 | T.T | main.rs:411:5:412:13 | struct S |
| main.rs:447:15:447:18 | SelfParam | | main.rs:440:5:441:19 | struct S |
| main.rs:447:15:447:18 | SelfParam | T | main.rs:446:10:446:10 | T |
| main.rs:447:26:449:9 | { ... } | | main.rs:446:10:446:10 | T |
| main.rs:448:13:448:16 | self | | main.rs:440:5:441:19 | struct S |
| main.rs:448:13:448:16 | self | T | main.rs:446:10:446:10 | T |
| main.rs:448:13:448:18 | self.0 | | main.rs:446:10:446:10 | T |
| main.rs:451:15:451:19 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:451:15:451:19 | SelfParam | &T | main.rs:440:5:441:19 | struct S |
| main.rs:451:15:451:19 | SelfParam | &T.T | main.rs:446:10:446:10 | T |
| main.rs:451:28:453:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:451:28:453:9 | { ... } | &T | main.rs:446:10:446:10 | T |
| main.rs:452:13:452:19 | &... | | file://:0:0:0:0 | & |
| main.rs:452:13:452:19 | &... | &T | main.rs:446:10:446:10 | T |
| main.rs:452:14:452:17 | self | | file://:0:0:0:0 | & |
| main.rs:452:14:452:17 | self | &T | main.rs:440:5:441:19 | struct S |
| main.rs:452:14:452:17 | self | &T.T | main.rs:446:10:446:10 | T |
| main.rs:452:14:452:19 | self.0 | | main.rs:446:10:446:10 | T |
| main.rs:455:15:455:25 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:455:15:455:25 | SelfParam | &T | main.rs:440:5:441:19 | struct S |
| main.rs:455:15:455:25 | SelfParam | &T.T | main.rs:446:10:446:10 | T |
| main.rs:455:34:457:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:455:34:457:9 | { ... } | &T | main.rs:446:10:446:10 | T |
| main.rs:456:13:456:19 | &... | | file://:0:0:0:0 | & |
| main.rs:456:13:456:19 | &... | &T | main.rs:446:10:446:10 | T |
| main.rs:456:14:456:17 | self | | file://:0:0:0:0 | & |
| main.rs:456:14:456:17 | self | &T | main.rs:440:5:441:19 | struct S |
| main.rs:456:14:456:17 | self | &T.T | main.rs:446:10:446:10 | T |
| main.rs:456:14:456:19 | self.0 | | main.rs:446:10:446:10 | T |
| main.rs:461:13:461:14 | x1 | | main.rs:440:5:441:19 | struct S |
| main.rs:461:13:461:14 | x1 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:461:18:461:22 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:461:18:461:22 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:461:20:461:21 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:462:26:462:27 | x1 | | main.rs:440:5:441:19 | struct S |
| main.rs:462:26:462:27 | x1 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:462:26:462:32 | x1.m1(...) | | main.rs:443:5:444:14 | struct S2 |
| main.rs:464:13:464:14 | x2 | | main.rs:440:5:441:19 | struct S |
| main.rs:464:13:464:14 | x2 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:464:18:464:22 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:464:18:464:22 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:464:20:464:21 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:466:26:466:27 | x2 | | main.rs:440:5:441:19 | struct S |
| main.rs:466:26:466:27 | x2 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:466:26:466:32 | x2.m2(...) | | file://:0:0:0:0 | & |
| main.rs:466:26:466:32 | x2.m2(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:467:26:467:27 | x2 | | main.rs:440:5:441:19 | struct S |
| main.rs:467:26:467:27 | x2 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:467:26:467:32 | x2.m3(...) | | file://:0:0:0:0 | & |
| main.rs:467:26:467:32 | x2.m3(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:469:13:469:14 | x3 | | main.rs:440:5:441:19 | struct S |
| main.rs:469:13:469:14 | x3 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:469:18:469:22 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:469:18:469:22 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:469:20:469:21 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:471:26:471:41 | ...::m2(...) | | file://:0:0:0:0 | & |
| main.rs:471:26:471:41 | ...::m2(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:471:38:471:40 | &x3 | | file://:0:0:0:0 | & |
| main.rs:471:38:471:40 | &x3 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:471:38:471:40 | &x3 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:471:39:471:40 | x3 | | main.rs:440:5:441:19 | struct S |
| main.rs:471:39:471:40 | x3 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:472:26:472:41 | ...::m3(...) | | file://:0:0:0:0 | & |
| main.rs:472:26:472:41 | ...::m3(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:472:38:472:40 | &x3 | | file://:0:0:0:0 | & |
| main.rs:472:38:472:40 | &x3 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:472:38:472:40 | &x3 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:472:39:472:40 | x3 | | main.rs:440:5:441:19 | struct S |
| main.rs:472:39:472:40 | x3 | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:474:13:474:14 | x4 | | file://:0:0:0:0 | & |
| main.rs:474:13:474:14 | x4 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:474:13:474:14 | x4 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:474:18:474:23 | &... | | file://:0:0:0:0 | & |
| main.rs:474:18:474:23 | &... | &T | main.rs:440:5:441:19 | struct S |
| main.rs:474:18:474:23 | &... | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:474:19:474:23 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:474:19:474:23 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:474:21:474:22 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:476:26:476:27 | x4 | | file://:0:0:0:0 | & |
| main.rs:476:26:476:27 | x4 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:476:26:476:27 | x4 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:476:26:476:32 | x4.m2(...) | | file://:0:0:0:0 | & |
| main.rs:476:26:476:32 | x4.m2(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:477:26:477:27 | x4 | | file://:0:0:0:0 | & |
| main.rs:477:26:477:27 | x4 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:477:26:477:27 | x4 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:477:26:477:32 | x4.m3(...) | | file://:0:0:0:0 | & |
| main.rs:477:26:477:32 | x4.m3(...) | &T | main.rs:443:5:444:14 | struct S2 |
| main.rs:479:13:479:14 | x5 | | file://:0:0:0:0 | & |
| main.rs:479:13:479:14 | x5 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:479:13:479:14 | x5 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:479:18:479:23 | &... | | file://:0:0:0:0 | & |
| main.rs:479:18:479:23 | &... | &T | main.rs:440:5:441:19 | struct S |
| main.rs:479:18:479:23 | &... | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:479:19:479:23 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:479:19:479:23 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:479:21:479:22 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:481:26:481:27 | x5 | | file://:0:0:0:0 | & |
| main.rs:481:26:481:27 | x5 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:481:26:481:27 | x5 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:481:26:481:32 | x5.m1(...) | | main.rs:443:5:444:14 | struct S2 |
| main.rs:482:26:482:27 | x5 | | file://:0:0:0:0 | & |
| main.rs:482:26:482:27 | x5 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:482:26:482:27 | x5 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:482:26:482:29 | x5.0 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:484:13:484:14 | x6 | | file://:0:0:0:0 | & |
| main.rs:484:13:484:14 | x6 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:484:13:484:14 | x6 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:484:18:484:23 | &... | | file://:0:0:0:0 | & |
| main.rs:484:18:484:23 | &... | &T | main.rs:440:5:441:19 | struct S |
| main.rs:484:18:484:23 | &... | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:484:19:484:23 | S(...) | | main.rs:440:5:441:19 | struct S |
| main.rs:484:19:484:23 | S(...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:484:21:484:22 | S2 | | main.rs:443:5:444:14 | struct S2 |
| main.rs:486:26:486:30 | (...) | | main.rs:440:5:441:19 | struct S |
| main.rs:486:26:486:30 | (...) | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:486:26:486:35 | ... .m1(...) | | main.rs:443:5:444:14 | struct S2 |
| main.rs:486:27:486:29 | * ... | | main.rs:440:5:441:19 | struct S |
| main.rs:486:27:486:29 | * ... | T | main.rs:443:5:444:14 | struct S2 |
| main.rs:486:28:486:29 | x6 | | file://:0:0:0:0 | & |
| main.rs:486:28:486:29 | x6 | &T | main.rs:440:5:441:19 | struct S |
| main.rs:486:28:486:29 | x6 | &T.T | main.rs:443:5:444:14 | struct S2 |
| main.rs:492:16:492:20 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:492:16:492:20 | SelfParam | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:494:16:494:20 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:494:16:494:20 | SelfParam | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:494:32:496:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:494:32:496:9 | { ... } | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:495:13:495:16 | self | | file://:0:0:0:0 | & |
| main.rs:495:13:495:16 | self | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:495:13:495:22 | self.foo(...) | | file://:0:0:0:0 | & |
| main.rs:495:13:495:22 | self.foo(...) | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:502:16:502:20 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:502:16:502:20 | SelfParam | &T | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:502:36:504:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:502:36:504:9 | { ... } | &T | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:503:13:503:16 | self | | file://:0:0:0:0 | & |
| main.rs:503:13:503:16 | self | &T | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:508:13:508:13 | x | | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:508:13:508:13 | x | | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:508:17:508:24 | MyStruct | | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:508:17:508:24 | MyStruct | | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:509:9:509:9 | x | | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:509:9:509:9 | x | | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:509:9:509:15 | x.bar(...) | | file://:0:0:0:0 | & |
| main.rs:509:9:509:15 | x.bar(...) | &T | main.rs:491:5:497:5 | trait MyTrait |
| main.rs:509:9:509:15 | x.bar(...) | &T | main.rs:499:5:499:20 | struct MyStruct |
| main.rs:519:16:519:20 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:519:16:519:20 | SelfParam | &T | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:519:16:519:20 | SelfParam | &T.T | main.rs:518:10:518:10 | T |
| main.rs:519:32:521:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:519:32:521:9 | { ... } | &T | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:519:32:521:9 | { ... } | &T.T | main.rs:518:10:518:10 | T |
| main.rs:520:13:520:16 | self | | file://:0:0:0:0 | & |
| main.rs:520:13:520:16 | self | &T | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:520:13:520:16 | self | &T.T | main.rs:518:10:518:10 | T |
| main.rs:525:13:525:13 | x | | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:525:13:525:13 | x | T | main.rs:514:5:514:13 | struct S |
| main.rs:525:17:525:27 | MyStruct(...) | | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:525:17:525:27 | MyStruct(...) | T | main.rs:514:5:514:13 | struct S |
| main.rs:525:26:525:26 | S | | main.rs:514:5:514:13 | struct S |
| main.rs:526:9:526:9 | x | | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:526:9:526:9 | x | T | main.rs:514:5:514:13 | struct S |
| main.rs:526:9:526:15 | x.foo(...) | | file://:0:0:0:0 | & |
| main.rs:526:9:526:15 | x.foo(...) | &T | main.rs:516:5:516:26 | struct MyStruct |
| main.rs:526:9:526:15 | x.foo(...) | &T.T | main.rs:514:5:514:13 | struct S |
| main.rs:534:15:534:19 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:534:15:534:19 | SelfParam | &T | main.rs:531:5:531:13 | struct S |
| main.rs:534:31:536:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:534:31:536:9 | { ... } | &T | main.rs:531:5:531:13 | struct S |
| main.rs:535:13:535:19 | &... | | file://:0:0:0:0 | & |
| main.rs:535:13:535:19 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:535:14:535:19 | &... | | file://:0:0:0:0 | & |
| main.rs:535:14:535:19 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:535:15:535:19 | &self | | file://:0:0:0:0 | & |
| main.rs:535:15:535:19 | &self | &T | main.rs:531:5:531:13 | struct S |
| main.rs:535:16:535:19 | self | | file://:0:0:0:0 | & |
| main.rs:535:16:535:19 | self | &T | main.rs:531:5:531:13 | struct S |
| main.rs:538:15:538:25 | SelfParam | | file://:0:0:0:0 | & |
| main.rs:538:15:538:25 | SelfParam | &T | main.rs:531:5:531:13 | struct S |
| main.rs:538:37:540:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:538:37:540:9 | { ... } | &T | main.rs:531:5:531:13 | struct S |
| main.rs:539:13:539:19 | &... | | file://:0:0:0:0 | & |
| main.rs:539:13:539:19 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:539:14:539:19 | &... | | file://:0:0:0:0 | & |
| main.rs:539:14:539:19 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:539:15:539:19 | &self | | file://:0:0:0:0 | & |
| main.rs:539:15:539:19 | &self | &T | main.rs:531:5:531:13 | struct S |
| main.rs:539:16:539:19 | self | | file://:0:0:0:0 | & |
| main.rs:539:16:539:19 | self | &T | main.rs:531:5:531:13 | struct S |
| main.rs:542:15:542:15 | x | | file://:0:0:0:0 | & |
| main.rs:542:15:542:15 | x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:542:34:544:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:542:34:544:9 | { ... } | &T | main.rs:531:5:531:13 | struct S |
| main.rs:543:13:543:13 | x | | file://:0:0:0:0 | & |
| main.rs:543:13:543:13 | x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:546:15:546:15 | x | | file://:0:0:0:0 | & |
| main.rs:546:15:546:15 | x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:546:34:548:9 | { ... } | | file://:0:0:0:0 | & |
| main.rs:546:34:548:9 | { ... } | &T | main.rs:531:5:531:13 | struct S |
| main.rs:547:13:547:16 | &... | | file://:0:0:0:0 | & |
| main.rs:547:13:547:16 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:547:14:547:16 | &... | | file://:0:0:0:0 | & |
| main.rs:547:14:547:16 | &... | &T | main.rs:531:5:531:13 | struct S |
| main.rs:547:15:547:16 | &x | | file://:0:0:0:0 | & |
| main.rs:547:15:547:16 | &x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:547:16:547:16 | x | | file://:0:0:0:0 | & |
| main.rs:547:16:547:16 | x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:552:13:552:13 | x | | main.rs:531:5:531:13 | struct S |
| main.rs:552:17:552:20 | S {...} | | main.rs:531:5:531:13 | struct S |
| main.rs:553:9:553:9 | x | | main.rs:531:5:531:13 | struct S |
| main.rs:553:9:553:14 | x.f1(...) | | file://:0:0:0:0 | & |
| main.rs:553:9:553:14 | x.f1(...) | &T | main.rs:531:5:531:13 | struct S |
| main.rs:554:9:554:9 | x | | main.rs:531:5:531:13 | struct S |
| main.rs:554:9:554:14 | x.f2(...) | | file://:0:0:0:0 | & |
| main.rs:554:9:554:14 | x.f2(...) | &T | main.rs:531:5:531:13 | struct S |
| main.rs:555:9:555:17 | ...::f3(...) | | file://:0:0:0:0 | & |
| main.rs:555:9:555:17 | ...::f3(...) | &T | main.rs:531:5:531:13 | struct S |
| main.rs:555:15:555:16 | &x | | file://:0:0:0:0 | & |
| main.rs:555:15:555:16 | &x | &T | main.rs:531:5:531:13 | struct S |
| main.rs:555:16:555:16 | x | | main.rs:531:5:531:13 | struct S |
| main.rs:560:5:560:11 | ...::f(...) | | main.rs:2:5:2:21 | struct Foo |
| main.rs:561:5:561:33 | ...::g(...) | | main.rs:2:5:2:21 | struct Foo |
| main.rs:561:11:561:20 | ...::Foo {...} | | main.rs:2:5:2:21 | struct Foo |
| main.rs:561:23:561:32 | ...::Foo {...} | | main.rs:2:5:2:21 | struct Foo |
resolveMethodCallExpr
| main.rs:23:9:23:14 | x.m1(...) | main.rs:5:9:7:9 | fn m1 |
| main.rs:24:9:24:14 | y.m2(...) | main.rs:9:9:11:9 | fn m2 |
| main.rs:67:26:67:31 | x.m2(...) | main.rs:52:9:54:9 | fn m2 |
| main.rs:68:26:68:31 | y.m2(...) | main.rs:52:9:54:9 | fn m2 |
| main.rs:95:9:95:14 | x.m1(...) | main.rs:84:9:84:25 | fn m1 |
| main.rs:143:13:143:21 | self.m1(...) | main.rs:137:9:137:25 | fn m1 |
| main.rs:148:9:148:14 | x.m1(...) | main.rs:137:9:137:25 | fn m1 |
| main.rs:161:26:161:31 | x.m1(...) | main.rs:152:9:154:9 | fn m1 |
| main.rs:162:26:162:31 | y.m1(...) | main.rs:152:9:154:9 | fn m1 |
| main.rs:167:26:167:31 | x.m2(...) | main.rs:139:9:144:9 | fn m2 |
| main.rs:168:26:168:31 | y.m2(...) | main.rs:139:9:144:9 | fn m2 |
| main.rs:206:26:206:31 | x.m1(...) | main.rs:199:9:201:9 | fn m1 |
| main.rs:209:26:209:31 | x.m2(...) | main.rs:184:9:190:9 | fn m2 |
| main.rs:238:26:238:31 | x.m1(...) | main.rs:226:9:231:9 | fn m1 |
| main.rs:239:26:239:31 | y.m1(...) | main.rs:226:9:231:9 | fn m1 |
| main.rs:269:17:269:25 | self.m1(...) | main.rs:260:9:260:25 | fn m1 |
| main.rs:282:17:282:25 | self.m2(...) | main.rs:264:9:273:9 | fn m2 |
| main.rs:311:26:311:31 | x.m1(...) | main.rs:290:9:292:9 | fn m1 |
| main.rs:312:26:312:31 | y.m1(...) | main.rs:290:9:292:9 | fn m1 |
| main.rs:317:26:317:31 | x.m2(...) | main.rs:264:9:273:9 | fn m2 |
| main.rs:318:26:318:31 | y.m2(...) | main.rs:264:9:273:9 | fn m2 |
| main.rs:323:26:323:31 | x.m3(...) | main.rs:277:9:286:9 | fn m3 |
| main.rs:324:26:324:31 | y.m3(...) | main.rs:277:9:286:9 | fn m3 |
| main.rs:388:13:388:27 | self.set(...) | main.rs:385:9:385:36 | fn set |
| main.rs:419:9:419:17 | x2.set(...) | main.rs:393:9:393:38 | fn set |
| main.rs:423:9:423:22 | x3.call_set(...) | main.rs:387:9:389:9 | fn call_set |
| main.rs:462:26:462:32 | x1.m1(...) | main.rs:447:9:449:9 | fn m1 |
| main.rs:466:26:466:32 | x2.m2(...) | main.rs:451:9:453:9 | fn m2 |
| main.rs:467:26:467:32 | x2.m3(...) | main.rs:455:9:457:9 | fn m3 |
| main.rs:476:26:476:32 | x4.m2(...) | main.rs:451:9:453:9 | fn m2 |
| main.rs:477:26:477:32 | x4.m3(...) | main.rs:455:9:457:9 | fn m3 |
| main.rs:481:26:481:32 | x5.m1(...) | main.rs:447:9:449:9 | fn m1 |
| main.rs:486:26:486:35 | ... .m1(...) | main.rs:447:9:449:9 | fn m1 |
| main.rs:495:13:495:22 | self.foo(...) | main.rs:492:9:492:31 | fn foo |
| main.rs:509:9:509:15 | x.bar(...) | main.rs:494:9:496:9 | fn bar |
| main.rs:526:9:526:15 | x.foo(...) | main.rs:519:9:521:9 | fn foo |
| main.rs:553:9:553:14 | x.f1(...) | main.rs:534:9:536:9 | fn f1 |
| main.rs:554:9:554:14 | x.f2(...) | main.rs:538:9:540:9 | fn f2 |
resolveFieldExpr
| main.rs:41:13:41:18 | self.a | main.rs:31:9:31:12 | RecordField |
| main.rs:47:23:47:28 | self.a | main.rs:31:9:31:12 | RecordField |
| main.rs:53:13:53:18 | self.a | main.rs:31:9:31:12 | RecordField |
| main.rs:100:13:100:18 | self.a | main.rs:75:9:75:12 | RecordField |
| main.rs:106:23:106:28 | self.a | main.rs:75:9:75:12 | RecordField |
| main.rs:153:13:153:18 | self.a | main.rs:128:9:128:12 | RecordField |
| main.rs:282:17:282:27 | ... .a | main.rs:246:9:246:12 | RecordField |
| main.rs:284:17:284:32 | ... .a | main.rs:246:9:246:12 | RecordField |
| main.rs:291:13:291:18 | self.a | main.rs:246:9:246:12 | RecordField |
| main.rs:299:26:299:31 | self.a | main.rs:251:9:251:12 | RecordField |
| main.rs:448:13:448:18 | self.0 | main.rs:441:17:441:17 | TupleField |
| main.rs:452:14:452:19 | self.0 | main.rs:441:17:441:17 | TupleField |
| main.rs:456:14:456:19 | self.0 | main.rs:441:17:441:17 | TupleField |
| main.rs:482:26:482:29 | x5.0 | main.rs:441:17:441:17 | TupleField |

View File

@@ -0,0 +1,18 @@
import rust
import codeql.rust.internal.TypeInference as TypeInference
import TypeInference
import utils.test.InlineExpectationsTest
query predicate inferType(AstNode n, TypePath path, Type t) {
t = TypeInference::inferType(n, path)
}
query predicate resolveMethodCallExpr(MethodCallExpr mce, Function f) {
f = resolveMethodCallExpr(mce)
}
query predicate resolveFieldExpr(FieldExpr fe, AstNode target) {
target = resolveRecordFieldExpr(fe)
or
target = resolveTupleFieldExpr(fe)
}

View File

@@ -1,7 +1,6 @@
| Multiple children | 0 |
| Multiple locations | 0 |
| Multiple parents | 0 |
| Multiple path resolutions | 0 |
| Multiple positions | 0 |
| Multiple primary QL classes | 0 |
| Multiple toStrings | 0 |

View File

@@ -8,6 +8,7 @@
| Files extracted - without errors % | 57 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Inconsistencies - Path resolution | 0 |
| Inconsistencies - data flow | 0 |
| Lines of code extracted | 60 |
| Lines of user code extracted | 60 |

View File

@@ -4,19 +4,18 @@ set -eu
set -o pipefail
export RUST_BACKTRACE=full
QLTEST_LOG="$CODEQL_EXTRACTOR_RUST_LOG_DIR"/qltest.log
mkdir -p "$CODEQL_EXTRACTOR_RUST_SCRATCH_DIR"
TMP_OUT="$(mktemp --tmpdir="$CODEQL_EXTRACTOR_RUST_SCRATCH_DIR" qltest-XXXXXX.log))"
trap 'rm -f "$TMP_OUT"' EXIT
QLTEST_LOG="$CODEQL_EXTRACTOR_RUST_LOG_DIR/qltest.log"
QLTEST_COLORED_LOG="$CODEQL_EXTRACTOR_RUST_SCRATCH_DIR/qltest.log"
dirname "$QLTEST_LOG" "$QLTEST_COLORED_LOG" | xargs mkdir -p
# put full-color output on the side, but remove the color codes from the log file
# also, print (colored) output only in case of failure
if ! "$CODEQL_EXTRACTOR_RUST_ROOT/tools/$CODEQL_PLATFORM/extractor" \
--qltest \
--logging-verbosity=progress+ \
2>&1 \
| tee "$TMP_OUT" \
| tee "$QLTEST_COLORED_LOG" \
| sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' \
> "$QLTEST_LOG"; then
cat "$TMP_OUT"
cat "$QLTEST_COLORED_LOG"
exit 1
fi