11private import rust
2- private import codeql.rust.internal.PathResolution
32private import codeql.rust.internal.TypeInference as TypeInference
43private import codeql.rust.elements.internal.ExprImpl:: Impl as ExprImpl
5- private import codeql.rust.elements.Operation
64
75module Impl {
8- newtype TArgumentPosition =
9- TPositionalArgumentPosition ( int i ) {
10- i in [ 0 .. max ( [ any ( ParamList l ) .getNumberOfParams ( ) , any ( ArgList l ) .getNumberOfArgs ( ) ] ) - 1 ]
11- } or
12- TSelfArgumentPosition ( )
13-
14- /** An argument position in a call. */
15- class ArgumentPosition extends TArgumentPosition {
16- /** Gets the index of the argument in the call, if this is a positional argument. */
17- int asPosition ( ) { this = TPositionalArgumentPosition ( result ) }
18-
19- /** Holds if this call position is a self argument. */
20- predicate isSelf ( ) { this instanceof TSelfArgumentPosition }
21-
22- /** Gets a string representation of this argument position. */
23- string toString ( ) {
24- result = this .asPosition ( ) .toString ( )
25- or
26- this .isSelf ( ) and result = "self"
27- }
28- }
29-
306 /**
317 * An expression that calls a function.
328 *
33- * This class abstracts over the different ways in which a function can be
34- * called in Rust.
9+ * Either a `CallExprBase`, an `Operation`, or an `IndexExpr`.
3510 */
3611 abstract class Call extends ExprImpl:: Expr {
37- /** Gets the argument at the given position, if any. */
38- abstract Expr getArgument ( ArgumentPosition pos ) ;
39-
40- /** Gets the number of arguments _excluding_ any `self` argument. */
41- int getNumberOfArguments ( ) { result = count ( this .getArgument ( TPositionalArgumentPosition ( _) ) ) }
42-
43- /** Gets the `i`th argument of this call, if any. */
44- Expr getPositionalArgument ( int i ) { result = this .getArgument ( TPositionalArgumentPosition ( i ) ) }
12+ /** Gets the `i`th positional argument of this call, if any. */
13+ Expr getPositionalArgument ( int i ) { none ( ) }
4514
46- /** Gets the receiver of this call if it is a method call. */
47- Expr getReceiver ( ) { result = this .getArgument ( TSelfArgumentPosition ( ) ) }
15+ /**
16+ * Gets the receiver of this call, if any.
17+ *
18+ * This is either an actual receiver of a method call, the first operand of an operation,
19+ * or the base expression of an index expression.
20+ */
21+ Expr getReceiverArgument ( ) { none ( ) }
4822
49- /** Gets the static target of this call, if any. */
50- Function getStaticTarget ( ) { result = TypeInference:: resolveCallTarget ( this ) }
23+ /** Gets the static target (function or tuple struct/variant) of this call, if any. */
24+ final Addressable getStaticTarget ( ) { result = TypeInference:: resolveCallTarget ( this ) }
5125
5226 /** Gets a runtime target of this call, if any. */
5327 pragma [ nomagic]
@@ -60,82 +34,4 @@ module Impl {
6034 )
6135 }
6236 }
63-
64- private predicate callHasQualifier ( CallExpr call , Path path , Path qualifier ) {
65- path = call .getFunction ( ) .( PathExpr ) .getPath ( ) and
66- qualifier = path .getQualifier ( )
67- }
68-
69- /** Holds if the call expression dispatches to a method. */
70- private predicate callIsMethodCall (
71- CallExpr call , Path qualifier , string methodName , boolean selfIsRef
72- ) {
73- exists ( Path path , Function f |
74- callHasQualifier ( call , path , qualifier ) and
75- f = resolvePath ( path ) and
76- path .getSegment ( ) .getIdentifier ( ) .getText ( ) = methodName and
77- exists ( SelfParam self |
78- self = f .getSelfParam ( ) and
79- if self .isRef ( ) then selfIsRef = true else selfIsRef = false
80- )
81- )
82- }
83-
84- class CallExprCall extends Call instanceof CallExpr {
85- CallExprCall ( ) { not callIsMethodCall ( this , _, _, _) }
86-
87- override Expr getArgument ( ArgumentPosition pos ) {
88- result = super .getArgList ( ) .getArg ( pos .asPosition ( ) )
89- }
90- }
91-
92- class CallExprMethodCall extends Call instanceof CallExpr {
93- string methodName ;
94- boolean selfIsRef ;
95-
96- CallExprMethodCall ( ) { callIsMethodCall ( this , _, methodName , selfIsRef ) }
97-
98- /**
99- * Holds if this call must have an explicit borrow for the `self` argument,
100- * because the corresponding parameter is `&self`. Explicit borrows are not
101- * needed when using method call syntax.
102- */
103- predicate hasExplicitSelfBorrow ( ) { selfIsRef = true }
104-
105- override Expr getArgument ( ArgumentPosition pos ) {
106- pos .isSelf ( ) and result = super .getArgList ( ) .getArg ( 0 )
107- or
108- result = super .getArgList ( ) .getArg ( pos .asPosition ( ) + 1 )
109- }
110- }
111-
112- private class MethodCallExprCall extends Call instanceof MethodCallExpr {
113- override Expr getArgument ( ArgumentPosition pos ) {
114- pos .isSelf ( ) and result = this .( MethodCallExpr ) .getReceiver ( )
115- or
116- result = super .getArgList ( ) .getArg ( pos .asPosition ( ) )
117- }
118- }
119-
120- private class OperatorCall extends Call instanceof Operation {
121- Trait trait ;
122- string methodName ;
123- int borrows ;
124-
125- OperatorCall ( ) { super .isOverloaded ( trait , methodName , borrows ) }
126-
127- override Expr getArgument ( ArgumentPosition pos ) {
128- pos .isSelf ( ) and result = super .getOperand ( 0 )
129- or
130- pos .asPosition ( ) = 0 and result = super .getOperand ( 1 )
131- }
132- }
133-
134- private class IndexCall extends Call instanceof IndexExpr {
135- override Expr getArgument ( ArgumentPosition pos ) {
136- pos .isSelf ( ) and result = super .getBase ( )
137- or
138- pos .asPosition ( ) = 0 and result = super .getIndex ( )
139- }
140- }
14137}
0 commit comments