@@ -5,29 +5,58 @@ private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
5
5
private import codeql.rust.elements.Operation
6
6
7
7
module 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
+
8
30
/**
9
31
* An expression that calls a function.
10
32
*
11
- * This class abstracts over the different ways in which a function can be called in Rust.
33
+ * This class abstracts over the different ways in which a function can be
34
+ * called in Rust.
12
35
*/
13
36
abstract class Call extends ExprImpl:: Expr {
14
- /** Gets the number of arguments _excluding_ any `self` argument. */
15
- abstract int getNumberOfArguments ( ) ;
16
-
17
- /** Gets the receiver of this call if it is a method call. */
18
- abstract Expr getReceiver ( ) ;
19
-
20
- /** Holds if the call has a receiver that might be implicitly borrowed. */
21
- abstract predicate receiverImplicitlyBorrowed ( ) ;
37
+ /** Holds if the receiver of this call is implicitly borrowed. */
38
+ predicate receiverImplicitlyBorrowed ( ) { this .implicitBorrowAt ( TSelfArgumentPosition ( ) ) }
22
39
23
40
/** Gets the trait targeted by this call, if any. */
24
41
abstract Trait getTrait ( ) ;
25
42
26
43
/** Gets the name of the method called if this call is a method call. */
27
44
abstract string getMethodName ( ) ;
28
45
46
+ /** Gets the argument at the given position, if any. */
47
+ abstract Expr getArgument ( ArgumentPosition pos ) ;
48
+
49
+ /** Holds if the argument at `pos` might be implicitly borrowed. */
50
+ abstract predicate implicitBorrowAt ( ArgumentPosition pos ) ;
51
+
52
+ /** Gets the number of arguments _excluding_ any `self` argument. */
53
+ int getNumberOfArguments ( ) { result = count ( this .getArgument ( TPositionalArgumentPosition ( _) ) ) }
54
+
29
55
/** Gets the `i`th argument of this call, if any. */
30
- abstract Expr getArgument ( int i ) ;
56
+ Expr getPositionalArgument ( int i ) { result = this .getArgument ( TPositionalArgumentPosition ( i ) ) }
57
+
58
+ /** Gets the receiver of this call if it is a method call. */
59
+ Expr getReceiver ( ) { result = this .getArgument ( TSelfArgumentPosition ( ) ) }
31
60
32
61
/** Gets the static target of this call, if any. */
33
62
Function getStaticTarget ( ) {
@@ -54,15 +83,13 @@ module Impl {
54
83
55
84
override string getMethodName ( ) { none ( ) }
56
85
57
- override Expr getReceiver ( ) { none ( ) }
58
-
59
86
override Trait getTrait ( ) { none ( ) }
60
87
61
- override predicate receiverImplicitlyBorrowed ( ) { none ( ) }
62
-
63
- override int getNumberOfArguments ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) }
88
+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { none ( ) }
64
89
65
- override Expr getArgument ( int i ) { result = super .getArgList ( ) .getArg ( i ) }
90
+ override Expr getArgument ( ArgumentPosition pos ) {
91
+ result = super .getArgList ( ) .getArg ( pos .asPosition ( ) )
92
+ }
66
93
}
67
94
68
95
private class CallExprMethodCall extends Call instanceof CallExpr {
@@ -73,8 +100,6 @@ module Impl {
73
100
74
101
override string getMethodName ( ) { result = methodName }
75
102
76
- override Expr getReceiver ( ) { result = super .getArgList ( ) .getArg ( 0 ) }
77
-
78
103
override Trait getTrait ( ) {
79
104
result = resolvePath ( qualifier ) and
80
105
// When the qualifier is `Self` and resolves to a trait, it's inside a
@@ -84,43 +109,50 @@ module Impl {
84
109
qualifier .toString ( ) != "Self"
85
110
}
86
111
87
- override predicate receiverImplicitlyBorrowed ( ) { none ( ) }
112
+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { none ( ) }
88
113
89
- override int getNumberOfArguments ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) - 1 }
90
-
91
- override Expr getArgument ( int i ) { result = super .getArgList ( ) .getArg ( i + 1 ) }
114
+ override Expr getArgument ( ArgumentPosition pos ) {
115
+ pos .isSelf ( ) and result = super .getArgList ( ) .getArg ( 0 )
116
+ or
117
+ result = super .getArgList ( ) .getArg ( pos .asPosition ( ) + 1 )
118
+ }
92
119
}
93
120
94
121
private class MethodCallExprCall extends Call instanceof MethodCallExpr {
95
122
override string getMethodName ( ) { result = super .getIdentifier ( ) .getText ( ) }
96
123
97
- override Expr getReceiver ( ) { result = this .( MethodCallExpr ) .getReceiver ( ) }
98
-
99
124
override Trait getTrait ( ) { none ( ) }
100
125
101
- override predicate receiverImplicitlyBorrowed ( ) { any ( ) }
126
+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { pos . isSelf ( ) }
102
127
103
- override int getNumberOfArguments ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) }
104
-
105
- override Expr getArgument ( int i ) { result = super .getArgList ( ) .getArg ( i ) }
128
+ override Expr getArgument ( ArgumentPosition pos ) {
129
+ pos .isSelf ( ) and result = this .( MethodCallExpr ) .getReceiver ( )
130
+ or
131
+ result = super .getArgList ( ) .getArg ( pos .asPosition ( ) )
132
+ }
106
133
}
107
134
108
135
private class OperatorCall extends Call instanceof Operation {
109
136
Trait trait ;
110
137
string methodName ;
138
+ int borrows ;
111
139
112
- OperatorCall ( ) { super .isOverloaded ( trait , methodName ) }
140
+ OperatorCall ( ) { super .isOverloaded ( trait , methodName , borrows ) }
113
141
114
142
override string getMethodName ( ) { result = methodName }
115
143
116
- override Expr getReceiver ( ) { result = super .getOperand ( 0 ) }
117
-
118
144
override Trait getTrait ( ) { result = trait }
119
145
120
- override predicate receiverImplicitlyBorrowed ( ) { none ( ) }
121
-
122
- override int getNumberOfArguments ( ) { result = super .getNumberOfOperands ( ) - 1 }
146
+ override predicate implicitBorrowAt ( ArgumentPosition pos ) {
147
+ pos .isSelf ( ) and borrows >= 1
148
+ or
149
+ pos .asPosition ( ) = 0 and borrows = 2
150
+ }
123
151
124
- override Expr getArgument ( int i ) { result = super .getOperand ( 1 ) and i = 0 }
152
+ override Expr getArgument ( ArgumentPosition pos ) {
153
+ pos .isSelf ( ) and result = super .getOperand ( 0 )
154
+ or
155
+ pos .asPosition ( ) = 0 and result = super .getOperand ( 1 )
156
+ }
125
157
}
126
158
}
0 commit comments