Skip to content

Commit 5c7d47e

Browse files
committed
wip
1 parent 17b773e commit 5c7d47e

2 files changed

Lines changed: 129 additions & 88 deletions

File tree

rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,15 @@ private module Input3 implements InputSig3 {
240240

241241
class AstNode = Rust::AstNode;
242242

243-
class Expr = Rust::Expr;
243+
final class Expr = ExprImpl;
244244

245-
class Cast extends CastExpr {
245+
abstract private class ExprImpl extends AstNode { }
246+
247+
private class ExprExpr extends ExprImpl, Rust::Expr { }
248+
249+
private class ArgListExpr extends ExprImpl, ArgList { }
250+
251+
class Cast extends Expr, CastExpr {
246252
TypeMention getType() { result = this.getTypeRepr() }
247253
}
248254

@@ -258,11 +264,15 @@ private module Input3 implements InputSig3 {
258264
AstNode getBody() { result = this.getExpr() }
259265
}
260266

261-
class ConditionalExpr extends IfExpr {
267+
class ConditionalExpr extends Expr instanceof IfExpr {
268+
Expr getCondition() { result = super.getCondition() }
269+
262270
Expr getThen() { result = super.getThen() }
271+
272+
Expr getElse() { result = super.getElse() }
263273
}
264274

265-
class BinaryExpr extends Rust::BinaryExpr {
275+
class BinaryExpr extends Expr, Rust::BinaryExpr {
266276
Expr getLeftOperand() { result = super.getLhs() }
267277

268278
Expr getRightOperand() { result = super.getRhs() }
@@ -276,7 +286,9 @@ private module Input3 implements InputSig3 {
276286

277287
class AssignExpr extends Assignment, Rust::AssignmentExpr { }
278288

279-
class ParenExpr = Rust::ParenExpr;
289+
class ParenExpr extends Expr instanceof Rust::ParenExpr {
290+
Expr getExpr() { result = super.getExpr() }
291+
}
280292

281293
final class Declaration = DeclarationImpl;
282294

@@ -389,7 +401,7 @@ private module Input3 implements InputSig3 {
389401
override TypeMention getType() { result = TupleField.super.getTypeRepr() }
390402
}
391403

392-
class FieldAccess extends FieldExpr {
404+
class FieldAccess extends Expr, FieldExpr {
393405
Expr getReceiver() { result = this.getContainer() }
394406

395407
Field getField() {
@@ -588,15 +600,11 @@ private module Input3 implements InputSig3 {
588600

589601
abstract Type getTypeArgument(int pos, TypePath path);
590602

591-
abstract AstNode getArgument(int i);
592-
593-
Parameterizable getTargetForTypeQualifierMatching() {
594-
result = CallExprImpl::getResolvedFunction(this)
595-
or
596-
result = this.(Construction).getTarget()
597-
}
603+
abstract Expr getArgument(int i);
598604

599605
abstract Parameterizable getTarget(string derefChainBorrow);
606+
607+
abstract Parameterizable getATargetForTypeQualifierMatching();
600608
}
601609

602610
private class AssocFunctionCall extends InvocationImpl instanceof AssocFunctionResolution::AssocFunctionCall
@@ -613,7 +621,7 @@ private module Input3 implements InputSig3 {
613621
result = getCallExprTypeArgument(this, pos, path)
614622
}
615623

616-
override AstNode getArgument(int i) {
624+
override Expr getArgument(int i) {
617625
exists(FunctionPosition pos |
618626
i = pos.asPosition() and
619627
result = super.getNodeAt(pos)
@@ -645,6 +653,10 @@ private module Input3 implements InputSig3 {
645653
result = super.resolveCallTarget(_, _, derefChain, borrow) // mutual recursion; resolving method calls requires resolving types and vice versa
646654
)
647655
}
656+
657+
override Parameterizable getATargetForTypeQualifierMatching() {
658+
result = CallExprImpl::getResolvedFunction(this)
659+
}
648660
}
649661

650662
private class NonAssocFunctionCall extends InvocationImpl instanceof NonAssocCallExpr,
@@ -657,7 +669,7 @@ private module Input3 implements InputSig3 {
657669
result = NonAssocCallExpr.super.getTypeArgument(pos, path)
658670
}
659671

660-
override AstNode getArgument(int i) {
672+
override Expr getArgument(int i) {
661673
exists(FunctionPosition pos |
662674
i = pos.asPosition() and
663675
result = super.getNodeAt(pos)
@@ -671,6 +683,10 @@ private module Input3 implements InputSig3 {
671683
result = this.getTarget() and
672684
derefChainBorrow = noDerefChainBorrow()
673685
}
686+
687+
override Parameterizable getATargetForTypeQualifierMatching() {
688+
none() // non-assoc function calls cannot have type qualifiers
689+
}
674690
}
675691

676692
abstract private class Construction extends InvocationImpl {
@@ -680,6 +696,8 @@ private module Input3 implements InputSig3 {
680696
result = this.getTarget() and
681697
derefChainBorrow = noDerefChainBorrow()
682698
}
699+
700+
override Parameterizable getATargetForTypeQualifierMatching() { result = this.getTarget() }
683701
}
684702

685703
private class NonAssocCallConstruction extends Construction, NonAssocCallExpr {
@@ -697,7 +715,7 @@ private module Input3 implements InputSig3 {
697715
none()
698716
}
699717

700-
override AstNode getArgument(int i) {
718+
override Expr getArgument(int i) {
701719
exists(FunctionPosition pos |
702720
i = pos.asPosition() and
703721
result = NonAssocCallExpr.super.getNodeAt(pos)
@@ -721,7 +739,7 @@ private module Input3 implements InputSig3 {
721739
}
722740

723741
private class StructExprConstruction extends StructConstruction, StructExpr {
724-
override AstNode getArgument(int i) {
742+
override Expr getArgument(int i) {
725743
result =
726744
this.getFieldExpr(pragma[only_bind_into](this.getNthStructField(i).getName().getText()))
727745
.getExpr()
@@ -732,7 +750,7 @@ private module Input3 implements InputSig3 {
732750
private class PathExprConstruction extends StructConstruction, PathExpr {
733751
PathExprConstruction() { not exists(CallExpr ce | this = ce.getFunction()) }
734752

735-
override AstNode getArgument(int i) { none() }
753+
override Expr getArgument(int i) { none() }
736754
}
737755

738756
pragma[nomagic]
@@ -764,32 +782,33 @@ private module Input3 implements InputSig3 {
764782

765783
pragma[nomagic]
766784
private Type inferInvocationArgumentTypeContextualDefault(
767-
Invocation invocation, int pos, AstNode n, DerefChain derefChain, BorrowKind borrow,
785+
Invocation invocation, int pos, Expr arg, DerefChain derefChain, BorrowKind borrow,
768786
TypePath path
769787
) {
770788
exists(string derefChainBorrow |
771789
decodeDerefChainBorrow(derefChainBorrow, derefChain, borrow) and
772790
result =
773-
M3::inferInvocationArgumentTypeContextualDefault(invocation, derefChainBorrow, pos, n, path)
791+
M3::inferInvocationArgumentTypeContextualDefault(invocation, derefChainBorrow, pos, arg,
792+
path)
774793
)
775794
}
776795

777796
/**
778-
* Gets the type of `n` at `path` after applying `derefChain`, where `n` is the
779-
* `self` argument of a method call.
797+
* Gets the type of `receiver` at `path` after applying `derefChain`, where
798+
* `receiver` is the `self` argument of a method call.
780799
*
781800
* The predicate recursively pops the head of `derefChain` until it becomes
782-
* empty, at which point the inferred type can be applied back to `n`.
801+
* empty, at which point the inferred type can be applied back to `receiver`.
783802
*/
784803
pragma[nomagic]
785804
private Type inferInvocationSelfArgumentTypeContextual(
786-
Invocation invocation, AstNode n, DerefChain derefChain, TypePath path
805+
Invocation invocation, Expr receiver, DerefChain derefChain, TypePath path
787806
) {
788807
exists(FunctionPosition pos, BorrowKind borrow, TypePath path0 |
789808
invocation.(AssocFunctionResolution::AssocFunctionCall).hasReceiverAtPos(pos) and
790809
result =
791-
inferInvocationArgumentTypeContextualDefault(invocation, pos.asPosition(), n, derefChain,
792-
borrow, path0)
810+
inferInvocationArgumentTypeContextualDefault(invocation, pos.asPosition(), receiver,
811+
derefChain, borrow, path0)
793812
|
794813
borrow.isNoBorrow() and
795814
path = path0
@@ -806,7 +825,7 @@ private module Input3 implements InputSig3 {
806825
DerefChain derefChain0, Type t0, TypePath path0, DerefImplItemNode impl, Type selfParamType,
807826
TypePath selfPath
808827
|
809-
t0 = inferInvocationSelfArgumentTypeContextual(invocation, n, derefChain0, path0) and
828+
t0 = inferInvocationSelfArgumentTypeContextual(invocation, receiver, derefChain0, path0) and
810829
derefChain0.isCons(impl, derefChain) and
811830
selfParamType = impl.resolveSelfTypeAt(selfPath)
812831
|
@@ -823,14 +842,14 @@ private module Input3 implements InputSig3 {
823842
)
824843
}
825844

826-
Type inferInvocationArgumentTypeContextual(AstNode n, TypePath path) {
845+
Type inferInvocationArgumentTypeContextual(Expr arg, TypePath path) {
827846
exists(Invocation invocation, FunctionPosition pos, TypePath path0 |
828847
result =
829-
inferInvocationArgumentTypeContextualDefault(invocation, pos.asPosition(), n, _, _, path0) and
848+
inferInvocationArgumentTypeContextualDefault(invocation, pos.asPosition(), arg, _, _, path0) and
830849
not invocation.(AssocFunctionResolution::AssocFunctionCall).hasReceiverAtPos(pos)
831850
or
832851
pos.asPosition() = 0 and
833-
result = inferInvocationSelfArgumentTypeContextual(invocation, n, DerefChain::nil(), path0) and
852+
result = inferInvocationSelfArgumentTypeContextual(invocation, arg, DerefChain::nil(), path0) and
834853
not path0.isEmpty()
835854
|
836855
if invocation.(AssocFunctionResolution::OperationAssocFunctionCall).implicitBorrowAt(pos, _)
@@ -865,10 +884,8 @@ private module Input3 implements InputSig3 {
865884

866885
class Closure extends Expr, Callable instanceof Rust::ClosureExpr { }
867886

868-
class ClosureParameterPseudoType = T::ClosureParameterPseudoType;
869-
870-
ClosureParameterPseudoType getClosureParameterPseudoType(Parameter p) {
871-
result = TClosureParameterPseudoType(p)
887+
class ClosureParameterPseudoType extends T::ClosureParameterPseudoType {
888+
Parameter getParameter() { result = this.getParam() }
872889
}
873890

874891
/**

0 commit comments

Comments
 (0)