@@ -6,17 +6,23 @@ private import TypeMention
66private import TypeInference
77
88private newtype TFunctionPosition =
9- TArgumentFunctionPosition ( ArgumentPosition pos ) or
9+ TArgumentFunctionPosition ( ArgumentPosition pos ) { not pos . isSelf ( ) } or
1010 TReturnFunctionPosition ( )
1111
1212/**
13- * A position of a type related to a function.
13+ * A function-call adjusted position of a type related to a function.
1414 *
15- * Either `self`, `return`, or a positional parameter index.
15+ * Either `return` or a positional parameter index, where `self` is translated
16+ * to position `0` and subsequent positional parameters at index `i` are
17+ * translated to position `i + 1`.
18+ *
19+ * Function-call adjusted positions are needed when resolving calls of the
20+ * form `Foo::f(x_1, ..., x_n)`, where we do not know up front whether `f` is a
21+ * method or a non-method, and hence we need to be able to match `x_1` against
22+ * both a potential `self` parameter and a potential first positional parameter
23+ * (and `x_2, ... x_n` against all subsequent positional parameters).
1624 */
1725class FunctionPosition extends TFunctionPosition {
18- predicate isSelf ( ) { this .asArgumentPosition ( ) .isSelf ( ) }
19-
2026 int asPosition ( ) { result = this .asArgumentPosition ( ) .asPosition ( ) }
2127
2228 predicate isPosition ( ) { exists ( this .asPosition ( ) ) }
@@ -25,29 +31,18 @@ class FunctionPosition extends TFunctionPosition {
2531
2632 predicate isTypeQualifier ( ) { this .asArgumentPosition ( ) .isTypeQualifier ( ) }
2733
28- predicate isSelfOrTypeQualifier ( ) { this .isSelf ( ) or this .isTypeQualifier ( ) }
29-
3034 predicate isReturn ( ) { this = TReturnFunctionPosition ( ) }
3135
32- /** Gets the corresponding position when `f` is invoked via a function call. */
33- bindingset [ f]
34- FunctionPosition getFunctionCallAdjusted ( Function f ) {
35- this .isReturn ( ) and
36- result = this
37- or
38- if f .hasSelfParam ( )
39- then
40- this .isSelf ( ) and result .asPosition ( ) = 0
41- or
42- result .asPosition ( ) = this .asPosition ( ) + 1
43- else result = this
44- }
45-
4636 TypeMention getTypeMention ( Function f ) {
47- this .isSelf ( ) and
48- result = getSelfParamTypeMention ( f .getSelfParam ( ) )
49- or
50- result = f .getParam ( this .asPosition ( ) ) .getTypeRepr ( )
37+ (
38+ if f instanceof Method
39+ then
40+ result = f .getParam ( this .asPosition ( ) - 1 ) .getTypeRepr ( )
41+ or
42+ result = getSelfParamTypeMention ( f .getSelfParam ( ) ) and
43+ this .asPosition ( ) = 0
44+ else result = f .getParam ( this .asPosition ( ) ) .getTypeRepr ( )
45+ )
5146 or
5247 this .isReturn ( ) and
5348 result = getReturnTypeMention ( f )
@@ -197,8 +192,7 @@ class AssocFunctionType extends MkAssocFunctionType {
197192 exists ( Function f , ImplOrTraitItemNode i , FunctionPosition pos | this .appliesTo ( f , i , pos ) |
198193 result = pos .getTypeMention ( f )
199194 or
200- pos .isSelf ( ) and
201- not f .hasSelfParam ( ) and
195+ pos .isTypeQualifier ( ) and
202196 result = [ i .( Impl ) .getSelfTy ( ) .( AstNode ) , i .( Trait ) .getName ( ) ]
203197 )
204198 }
@@ -209,7 +203,7 @@ class AssocFunctionType extends MkAssocFunctionType {
209203}
210204
211205pragma [ nomagic]
212- private Trait getALookupTrait ( Type t ) {
206+ Trait getALookupTrait ( Type t ) {
213207 result = t .( TypeParamTypeParameter ) .getTypeParam ( ) .( TypeParamItemNode ) .resolveABound ( )
214208 or
215209 result = t .( SelfTypeParameter ) .getTrait ( )
@@ -310,10 +304,11 @@ signature module ArgsAreInstantiationsOfInputSig {
310304 * Holds if `f` inside `i` needs to have the type corresponding to type parameter
311305 * `tp` checked.
312306 *
313- * If `i` is an inherent implementation, ` tp` is a type parameter of the type being
314- * implemented, otherwise `tp` is a type parameter of the trait (being implemented) .
307+ * ` tp` is a type parameter of the trait being implemented by `f` or the trait to which
308+ * `f` belongs .
315309 *
316- * `pos` is one of the positions in `f` in which the relevant type occours.
310+ * `pos` is one of the function-call adjusted positions in `f` in which the relevant
311+ * type occurs.
317312 */
318313 predicate toCheck ( ImplOrTraitItemNode i , Function f , TypeParameter tp , FunctionPosition pos ) ;
319314
@@ -360,7 +355,7 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
360355 private newtype TCallAndPos =
361356 MkCallAndPos ( Input:: Call call , FunctionPosition pos ) { exists ( call .getArgType ( pos , _) ) }
362357
363- /** A call tagged with a position. */
358+ /** A call tagged with a function-call adjusted position. */
364359 private class CallAndPos extends MkCallAndPos {
365360 Input:: Call call ;
366361 FunctionPosition pos ;
@@ -413,20 +408,21 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
413408
414409 pragma [ nomagic]
415410 private predicate argIsInstantiationOf (
416- Input:: Call call , FunctionPosition pos , ImplOrTraitItemNode i , Function f , int rnk
411+ Input:: Call call , ImplOrTraitItemNode i , Function f , int rnk
417412 ) {
418- ArgIsInstantiationOfToIndex:: argIsInstantiationOf ( MkCallAndPos ( call , pos ) , i , _) and
419- toCheckRanked ( i , f , _, pos , rnk )
413+ exists ( FunctionPosition pos |
414+ ArgIsInstantiationOfToIndex:: argIsInstantiationOf ( MkCallAndPos ( call , pos ) , i , _) and
415+ toCheckRanked ( i , f , _, pos , rnk )
416+ )
420417 }
421418
422419 pragma [ nomagic]
423420 private predicate argsAreInstantiationsOfToIndex (
424421 Input:: Call call , ImplOrTraitItemNode i , Function f , int rnk
425422 ) {
426- exists ( FunctionPosition pos |
427- argIsInstantiationOf ( call , pos , i , f , rnk ) and
428- call .hasTargetCand ( i , f )
429- |
423+ argIsInstantiationOf ( call , i , f , rnk ) and
424+ call .hasTargetCand ( i , f ) and
425+ (
430426 rnk = 0
431427 or
432428 argsAreInstantiationsOfToIndex ( call , i , f , rnk - 1 )
0 commit comments