@@ -5,29 +5,58 @@ private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
55private import codeql.rust.elements.Operation
66
77module 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+
830 /**
931 * An expression that calls a function.
1032 *
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.
1235 */
1336 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 ( ) ) }
2239
2340 /** Gets the trait targeted by this call, if any. */
2441 abstract Trait getTrait ( ) ;
2542
2643 /** Gets the name of the method called if this call is a method call. */
2744 abstract string getMethodName ( ) ;
2845
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+
2955 /** 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 ( ) ) }
3160
3261 /** Gets the static target of this call, if any. */
3362 Function getStaticTarget ( ) {
@@ -54,15 +83,13 @@ module Impl {
5483
5584 override string getMethodName ( ) { none ( ) }
5685
57- override Expr getReceiver ( ) { none ( ) }
58-
5986 override Trait getTrait ( ) { none ( ) }
6087
61- override predicate receiverImplicitlyBorrowed ( ) { none ( ) }
62-
63- override int getNumberOfArguments ( ) { result = super .getArgList ( ) .getNumberOfArgs ( ) }
88+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { none ( ) }
6489
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+ }
6693 }
6794
6895 private class CallExprMethodCall extends Call instanceof CallExpr {
@@ -73,8 +100,6 @@ module Impl {
73100
74101 override string getMethodName ( ) { result = methodName }
75102
76- override Expr getReceiver ( ) { result = super .getArgList ( ) .getArg ( 0 ) }
77-
78103 override Trait getTrait ( ) {
79104 result = resolvePath ( qualifier ) and
80105 // When the qualifier is `Self` and resolves to a trait, it's inside a
@@ -84,43 +109,50 @@ module Impl {
84109 qualifier .toString ( ) != "Self"
85110 }
86111
87- override predicate receiverImplicitlyBorrowed ( ) { none ( ) }
112+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { none ( ) }
88113
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+ }
92119 }
93120
94121 private class MethodCallExprCall extends Call instanceof MethodCallExpr {
95122 override string getMethodName ( ) { result = super .getIdentifier ( ) .getText ( ) }
96123
97- override Expr getReceiver ( ) { result = this .( MethodCallExpr ) .getReceiver ( ) }
98-
99124 override Trait getTrait ( ) { none ( ) }
100125
101- override predicate receiverImplicitlyBorrowed ( ) { any ( ) }
126+ override predicate implicitBorrowAt ( ArgumentPosition pos ) { pos . isSelf ( ) }
102127
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+ }
106133 }
107134
108135 private class OperatorCall extends Call instanceof Operation {
109136 Trait trait ;
110137 string methodName ;
138+ int borrows ;
111139
112- OperatorCall ( ) { super .isOverloaded ( trait , methodName ) }
140+ OperatorCall ( ) { super .isOverloaded ( trait , methodName , borrows ) }
113141
114142 override string getMethodName ( ) { result = methodName }
115143
116- override Expr getReceiver ( ) { result = super .getOperand ( 0 ) }
117-
118144 override Trait getTrait ( ) { result = trait }
119145
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+ }
123151
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+ }
125157 }
126158}
0 commit comments