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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions rust/ql/consistency-queries/TypeInferenceConsistency.qlref
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: TypeInferenceConsistency.ql
postprocess: utils/test/ExternalLocationPostProcessing.ql
6 changes: 6 additions & 0 deletions rust/ql/lib/codeql/rust/internal/typeinference/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ abstract class TypeParameter extends Type {
override TypeParameter getPositionalTypeParameter(int i) { none() }

abstract ItemNode getDeclaringItem();

AstNode getScope() { result = this.getDeclaringItem() }
}

private class RawTypeParameter = @type_param or @trait or @type_alias or @impl_trait_type_repr;
Expand Down Expand Up @@ -583,6 +585,8 @@ class ImplTraitTypeParameter extends TypeParameter, TImplTraitTypeParameter {

override ItemNode getDeclaringItem() { none() }

override AstNode getScope() { result = implTrait.getFunction() }

override string toString() { result = "impl(" + typeParam.toString() + ")" }

override Location getLocation() { result = typeParam.getLocation() }
Expand Down Expand Up @@ -633,6 +637,8 @@ class ImplTraitTypeTypeParameter extends ImplTraitType, TypeParameter {

override ItemNode getDeclaringItem() { none() }

override AstNode getScope() { result = function }

override Function getFunction() { result = function }

override TypeParameter getPositionalTypeParameter(int i) { none() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2272,7 +2272,11 @@ private module Input3 implements InputSig3 {
BoolType() { this.getTypeItem() instanceof Builtins::Bool }
}

class AstNode = Rust::AstNode;
class AstNode extends Rust::AstNode {
AstNode getParent() { result = this.getParentNode() }
}

AstNode getTypeParameterScope(TypeParameter tp) { result = tp.getScope() }

final class Expr = ExprImpl;

Expand All @@ -2286,13 +2290,13 @@ private module Input3 implements InputSig3 {
TypeMention getType() { result = this.getTypeRepr() }
}

class Switch extends Rust::MatchExpr {
class Switch extends Expr, Rust::MatchExpr {
Expr getExpr() { result = this.getScrutinee() }

Case getCase(int index) { result = this.getArm(index) }
}

class Case extends Rust::MatchArm {
class Case extends AstNode, Rust::MatchArm {
AstNode getAPattern() { result = this.getPat() }

AstNode getBody() { result = this.getExpr() }
Expand Down Expand Up @@ -2449,8 +2453,8 @@ private module Input3 implements InputSig3 {
// mutual recursion; resolving fields requires resolving types and vice versa
result =
[
resolveStructFieldExpr(this, _).(AstNode),
resolveTupleFieldExpr(this, _)
resolveStructFieldExpr(this, _).(Field),
resolveTupleFieldExpr(this, _).(Field)
]
}
}
Expand Down Expand Up @@ -2480,7 +2484,7 @@ private module Input3 implements InputSig3 {
)
}

class Return extends ReturnExpr {
class Return extends Expr, ReturnExpr {
Expr getExpr() { result = super.getExpr() }
}

Expand Down Expand Up @@ -2583,15 +2587,15 @@ private module Input3 implements InputSig3 {
override TypeItem getTypeItem() { result = this }

override Parameter getParameter(int i) {
result = [super.getTupleField(i).(AstNode), super.getNthStructField(i)]
result = [super.getTupleField(i).(Parameter), super.getNthStructField(i).(Parameter)]
}
}

private class VariantConstructor extends ConstructorImpl instanceof Variant {
override TypeItem getTypeItem() { result = super.getEnum() }

override Parameter getParameter(int i) {
result = [super.getTupleField(i).(AstNode), super.getNthStructField(i)]
result = [super.getTupleField(i).(Parameter), super.getNthStructField(i).(Parameter)]
}
}

Expand Down Expand Up @@ -3155,7 +3159,7 @@ module Consistency = M3::Consistency;

module CachedStage = M3::CachedStage;

private predicate typeTestAstNodeRepr(AstNode n, string repr) {
private predicate typeTestAstNodeRepr(Input3::AstNode n, string repr) {
repr = [n.toString(), n.(IdentPat).getName().getText()]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
typeParameterEscapesScope
| test.rs:83:17:83:20 | data | B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:83:17:83:20 | data | B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:83:24:83:43 | await ... | E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:83:24:83:43 | await ... | T.B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:83:24:83:44 | TryExpr | B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:84:18:84:22 | &data | TRef.B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:84:19:84:22 | data | B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:86:25:86:28 | data | B | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:92:23:92:33 | Some(...) | T.E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:92:23:92:33 | Some(...) | T.T.T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:92:28:92:32 | frame | E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:92:28:92:32 | frame | E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:92:28:92:32 | frame | T.T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:92:28:92:32 | frame | T.T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:92:37:92:58 | await ... | T.E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:92:37:92:58 | await ... | T.T.T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:24:93:33 | Some(...) | T.TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:29:93:32 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:29:93:32 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:37:93:41 | frame | E | {EXTERNAL LOCATION} | T::Error[Body] |
| test.rs:93:37:93:41 | frame | T.T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:37:93:42 | TryExpr | T | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:93:37:93:53 | ... .data_ref() | T.TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:94:49:94:52 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:95:26:95:29 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:96:26:96:29 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:97:33:97:36 | data | TRef | {EXTERNAL LOCATION} | T::Data[Body] |
| test.rs:557:18:557:42 | await ... | T | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:557:18:557:51 | ... .unwrap() | | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:558:23:558:32 | Some(...) | T | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:558:28:558:31 | line | | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:558:28:558:31 | line | | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:558:36:558:60 | await ... | T | {EXTERNAL LOCATION} | St::Item[Stream] |
| test.rs:559:22:559:25 | line | | {EXTERNAL LOCATION} | St::Item[Stream] |
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
typeParameterEscapesScope
| main.rs:405:26:410:9 | { ... } | | main.rs:380:7:380:7 | T |
| main.rs:409:13:409:19 | ...::c | | main.rs:380:7:380:7 | T |
| main.rs:466:9:470:12 | ...::c | | main.rs:380:7:380:7 | T |
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
typeParameterEscapesScope
| main.rs:2240:9:2240:31 | ... .my_add(...) | T.T | main.rs:2126:10:2126:17 | T::Output[MyAdd] |
| main.rs:2240:9:2240:31 | ... .my_add(...) | T.T | main.rs:2135:10:2135:17 | T::Output[MyAdd] |
| main.rs:2240:9:2240:31 | ... .my_add(...) | T.T | main.rs:2144:14:2144:14 | T::Output[MyAdd] |
| main.rs:2296:13:2296:13 | s | | {EXTERNAL LOCATION} | I::Item[Iterator] |
| main.rs:2296:13:2296:13 | s | | {EXTERNAL LOCATION} | I::Item[Iterator] |
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
typeParameterEscapesScope
| sqlx.rs:43:61:43:80 | await ... | T.DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:43:61:43:81 | TryExpr | DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:169:9:169:16 | mut conn | DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:169:13:169:16 | conn | DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:169:20:169:39 | await ... | T.DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:169:20:169:40 | TryExpr | DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:179:13:179:16 | conn | DB | {EXTERNAL LOCATION} | DB |
| sqlx.rs:181:17:181:20 | conn | DB | {EXTERNAL LOCATION} | DB |
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
typeParameterEscapesScope
| test_storage.rs:64:9:64:17 | mut conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:64:13:64:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:64:21:64:41 | await ... | T.DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:64:21:64:42 | TryExpr | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:85:13:85:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:86:13:86:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:87:13:87:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:88:13:88:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:89:13:89:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:90:13:90:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:91:13:91:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:92:13:92:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:93:13:93:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:94:13:94:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:95:13:95:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:96:13:96:17 | conn1 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:131:9:131:17 | mut conn3 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:131:13:131:17 | conn3 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:131:21:131:41 | await ... | T.DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:131:21:131:42 | TryExpr | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:134:13:134:17 | conn3 | DB | {EXTERNAL LOCATION} | DB |
| test_storage.rs:135:13:135:17 | conn3 | DB | {EXTERNAL LOCATION} | DB |
Original file line number Diff line number Diff line change
Expand Up @@ -2140,13 +2140,24 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {

/** An AST node. */
class AstNode {
/** Gets the parent of this AST node, if any. */
AstNode getParent();

/** Gets a textual representation of this AST node. */
string toString();

/** Gets the location of this AST node. */
Location getLocation();
}

/**
* Gets the scope of type parameter `tp`.
*
* Only used in a consistency check to ensure that type parameters do not
* escape their scope.
*/
AstNode getTypeParameterScope(TypeParameter tp);

/** An expression. */
class Expr extends AstNode;

Expand Down Expand Up @@ -3747,6 +3758,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
Input3::inferTypeForDefaults(n, path) = t and
not inferType(n, path) = t
}

query predicate typeParameterEscapesScope(AstNode n, TypePath path, TypeParameter tp) {
tp = inferType(n, path) and
not n.getParent*() = getTypeParameterScope(tp)
}
}

/**
Expand Down
12 changes: 12 additions & 0 deletions unified/ql/lib/codeql/unified/internal/typeinference/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ abstract class TypeParameter extends TypeImpl {
override TypeParameter getPositionalTypeParameter(int i) { none() }

abstract Member getDeclaringItem();

Member getScope() { result = this.getDeclaringItem() }
}

private class IdAstNode =
Expand Down Expand Up @@ -241,6 +243,12 @@ class TypeParameterType extends TypeParameter, TTypeParameterType {
typeParam = result.(Unified::FunctionDeclaration).getATypeParameter()
}

override Member getScope() {
result = super.getScope()
or
result.(ClassLikeDeclaration).resolve().getEnclosingClassResolved*() = this.getDeclaringItem()
}

override Identifier getNameNode() { result = typeParam.getNameNode() }

override string toString() { result = typeParam.getName() }
Expand All @@ -262,6 +270,8 @@ class AssociatedTypeParameterType extends TypeParameter, TAssociatedTypeParamete

override ClassLikeDeclaration getDeclaringItem() { result = c }

override ClassLikeDeclaration getScope() { result.resolve() = c }

override Identifier getNameNode() { result = assocTypeDecl.getNameNode() }

override string toString() {
Expand Down Expand Up @@ -307,6 +317,8 @@ class ParentTypeParameterType extends TypeParameter, TParentTypeParameterType {

override Member getDeclaringItem() { result = m }

override Member getScope() { none() }

override Identifier getNameNode() { none() }

override string toString() { result = "(parent:" + m.getNameOrFallback() + ")" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ module Input3 implements InputSig3 {

class AstNode = Unified::AstNode;

AstNode getTypeParameterScope(TypeParameter tp) { result = tp.getScope() }

class Expr extends Unified::Expr {
Expr() {
isInAssignmentContext(this, _) or
Expand Down
Loading