@@ -298,14 +298,17 @@ private class FunctionDeclaration extends Function {
298298 }
299299
300300 pragma [ nomagic]
301- Type getParameterType ( ImplOrTraitItemNodeOption i , FunctionPosition pos , TypePath path ) {
301+ Type getParameterType ( ImplOrTraitItemNodeOption i , FunctionPosition posAdj , TypePath path ) {
302302 i = parent and
303303 (
304- not pos .isReturn ( ) and
305- result = getAssocFunctionTypeAt ( this , i .asSome ( ) , pos , path )
304+ exists ( FunctionPosition pos |
305+ not pos .isReturn ( ) and
306+ result = getAssocFunctionTypeAt ( this , i .asSome ( ) , pos , path ) and
307+ posAdj = pos .getFunctionCallAdjusted ( this )
308+ )
306309 or
307310 i .isNone ( ) and
308- result = this .getParam ( pos .asPosition ( ) ) .getTypeRepr ( ) .( TypeMention ) .getTypeAt ( path )
311+ result = this .getParam ( posAdj .asPosition ( ) ) .getTypeRepr ( ) .( TypeMention ) .getTypeAt ( path )
309312 )
310313 }
311314
@@ -1555,32 +1558,6 @@ private module AssocFunctionResolution {
15551558 AssocFunctionTraitIsVisible:: traitIsVisible ( afc , impl .resolveTraitTy ( ) )
15561559 }
15571560
1558- private Type getNonTypeParameterTypeQualifier ( AssocFunctionCall afc ) {
1559- result = getCallExprTypeQualifier ( afc , TypePath:: nil ( ) , _) and
1560- not result instanceof TypeParameter
1561- }
1562-
1563- pragma [ nomagic]
1564- private predicate callInfo (
1565- AssocFunctionCall afc , string name , int arity , TypeOption typeQualifier ,
1566- TypeOption traitQualifier , boolean hasReceiver
1567- ) {
1568- afc .hasNameAndArity ( name , arity ) and
1569- ( if afc .hasReceiver ( ) then hasReceiver = true else hasReceiver = false ) and
1570- (
1571- typeQualifier .asSome ( ) = getNonTypeParameterTypeQualifier ( afc )
1572- or
1573- not exists ( getNonTypeParameterTypeQualifier ( afc ) ) and
1574- typeQualifier .isNone ( )
1575- ) and
1576- (
1577- traitQualifier .asSome ( ) = TTrait ( afc .getATrait ( ) )
1578- or
1579- not afc .hasATrait ( ) and
1580- traitQualifier .isNone ( )
1581- )
1582- }
1583-
15841561 bindingset [ implType, trait, isMethod]
15851562 private predicate callMatching (
15861563 TypeOption implType , TypeOption trait , boolean isMethod , TypeOption typeQualifier ,
@@ -1641,7 +1618,7 @@ private module AssocFunctionResolution {
16411618 string name , int arity , TypeOption typeQualifier , TypeOption traitQualifier ,
16421619 boolean hasReceiver
16431620 |
1644- callInfo ( afc , name , arity , typeQualifier , traitQualifier , hasReceiver ) and
1621+ afc . hasSyntacticInfo ( name , arity , typeQualifier , traitQualifier , hasReceiver ) and
16451622 if not afc .hasATrait ( ) and i .( Impl ) .hasTrait ( )
16461623 then callVisibleImplTraitCandidate ( afc , i )
16471624 else any ( )
@@ -1686,14 +1663,19 @@ private module AssocFunctionResolution {
16861663 AssocFunctionType self , TypePath blanketPath , TypeParam blanketTypeParam
16871664 ) {
16881665 exists ( string name , int arity , TypeOption traitQualifier , boolean hasReceiver |
1689- callInfo ( afc , name , arity , _, traitQualifier , hasReceiver ) and
1666+ afc . hasSyntacticInfo ( name , arity , _, traitQualifier , hasReceiver ) and
16901667 assocFunctionSelfInfoBlanketLikeCand ( f , name , arity , selfPosAdj , impl , self , blanketPath ,
16911668 blanketTypeParam , traitQualifier , hasReceiver )
16921669 |
16931670 if not afc .hasATrait ( ) then callVisibleImplTraitCandidate ( afc , impl ) else any ( )
16941671 )
16951672 }
16961673
1674+ private Type getNonTypeParameterTypeQualifier ( AssocFunctionCall afc ) {
1675+ result = getCallExprTypeQualifier ( afc , TypePath:: nil ( ) , _) and
1676+ not result instanceof TypeParameter
1677+ }
1678+
16971679 /**
16981680 * A (potential) call to an associated function.
16991681 *
@@ -1746,6 +1728,31 @@ private module AssocFunctionResolution {
17461728
17471729 predicate hasATrait ( ) { exists ( this .getATrait ( ) ) }
17481730
1731+ /**
1732+ * Holds if this call has the given purely syntactic information, that is,
1733+ * information that does not rely on type inference.
1734+ */
1735+ pragma [ nomagic]
1736+ predicate hasSyntacticInfo (
1737+ string name , int arity , TypeOption typeQualifier , TypeOption traitQualifier ,
1738+ boolean hasReceiver
1739+ ) {
1740+ this .hasNameAndArity ( name , arity ) and
1741+ ( if this .hasReceiver ( ) then hasReceiver = true else hasReceiver = false ) and
1742+ (
1743+ typeQualifier .asSome ( ) = getNonTypeParameterTypeQualifier ( this )
1744+ or
1745+ not exists ( getNonTypeParameterTypeQualifier ( this ) ) and
1746+ typeQualifier .isNone ( )
1747+ ) and
1748+ (
1749+ traitQualifier .asSome ( ) = TTrait ( this .getATrait ( ) )
1750+ or
1751+ not this .hasATrait ( ) and
1752+ traitQualifier .isNone ( )
1753+ )
1754+ }
1755+
17491756 Type getTypeAt ( FunctionPosition posAdj , TypePath path ) {
17501757 result = inferType ( this .getNodeAt ( posAdj ) , path )
17511758 }
@@ -2420,7 +2427,7 @@ private module AssocFunctionResolution {
24202427 or
24212428 selfPosAdj_ .asPosition ( ) = 0 and hasReceiver = true
24222429 |
2423- callInfo ( afc_ , name , arity , typeQualifier , traitQualifier , _) and
2430+ afc_ . hasSyntacticInfo ( name , arity , typeQualifier , traitQualifier , _) and
24242431 this .hasSignature ( _, selfPosAdj_ , strippedTypePath , strippedType , name , arity ) and
24252432 forall ( Impl i |
24262433 i .isInherent ( ) and
@@ -2718,7 +2725,7 @@ private module AssocFunctionResolution {
27182725
27192726/**
27202727 * A matching configuration for resolving types of function call expressions
2721- * like `foo.bar(baz)`.
2728+ * like `foo.bar(baz)` and `Foo::bar(baz)` .
27222729 */
27232730private module FunctionCallMatchingInput implements MatchingWithEnvironmentInputSig {
27242731 import FunctionPositionMatchingInput
@@ -2741,10 +2748,10 @@ private module FunctionCallMatchingInput implements MatchingWithEnvironmentInput
27412748 result = f .getTypeParameter ( i , ppos )
27422749 }
27432750
2744- Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
2745- result = f .getParameterType ( i , dpos , path )
2751+ Type getDeclaredType ( FunctionPosition posAdj , TypePath path ) {
2752+ result = f .getParameterType ( i , posAdj , path )
27462753 or
2747- dpos .isReturn ( ) and
2754+ posAdj .isReturn ( ) and
27482755 result = f .getReturnType ( i , path )
27492756 }
27502757
@@ -2816,25 +2823,25 @@ private module FunctionCallMatchingInput implements MatchingWithEnvironmentInput
28162823 }
28172824
28182825 pragma [ nomagic]
2819- private Type getInferredSelfType ( FunctionPosition pos , string derefChainBorrow , TypePath path ) {
2826+ private Type getInferredSelfType ( FunctionPosition posAdj , string derefChainBorrow , TypePath path ) {
28202827 exists ( DerefChain derefChain , BorrowKind borrow |
2821- result = super .getSelfTypeAt ( pos . getFunctionCallAdjusted ( ) , derefChain , borrow , path ) and
2828+ result = super .getSelfTypeAt ( posAdj , derefChain , borrow , path ) and
28222829 derefChainBorrow = encodeDerefChainBorrow ( derefChain , borrow ) and
2823- pos . isSelf ( )
2830+ super . hasReceiverPos ( posAdj )
28242831 )
28252832 }
28262833
28272834 pragma [ nomagic]
2828- private Type getInferredNonSelfType ( FunctionPosition pos , TypePath path ) {
2829- result = super .getTypeAt ( pos . getFunctionCallAdjusted ( ) , path ) and
2830- not pos . isSelf ( )
2835+ private Type getInferredNonSelfType ( FunctionPosition posAdj , TypePath path ) {
2836+ result = super .getTypeAt ( posAdj , path ) and
2837+ not super . hasReceiverPos ( posAdj )
28312838 }
28322839
28332840 bindingset [ derefChainBorrow]
2834- override Type getInferredType ( string derefChainBorrow , FunctionPosition pos , TypePath path ) {
2835- result = this .getInferredSelfType ( pos , derefChainBorrow , path )
2841+ override Type getInferredType ( string derefChainBorrow , FunctionPosition posAdj , TypePath path ) {
2842+ result = this .getInferredSelfType ( posAdj , derefChainBorrow , path )
28362843 or
2837- result = this .getInferredNonSelfType ( pos , path )
2844+ result = this .getInferredNonSelfType ( posAdj , path )
28382845 }
28392846
28402847 Method getTarget ( ImplOrTraitItemNode i , string derefChainBorrow ) {
@@ -2882,24 +2889,22 @@ private module FunctionCallMatching = MatchingWithEnvironment<FunctionCallMatchi
28822889
28832890pragma [ nomagic]
28842891private Type inferFunctionCallType0 (
2885- FunctionCallMatchingInput:: Access a , FunctionCallMatchingInput :: AccessPosition apos , AstNode n ,
2886- DerefChain derefChain , BorrowKind borrow , TypePath path
2892+ FunctionCallMatchingInput:: Access a , FunctionPosition posAdj , AstNode n , DerefChain derefChain ,
2893+ BorrowKind borrow , TypePath path
28872894) {
28882895 exists ( TypePath path0 |
2889- exists ( FunctionPosition posAdj |
2890- n = a .getNodeAt ( posAdj ) and
2891- posAdj = apos .getFunctionCallAdjusted ( )
2892- |
2896+ n = a .getNodeAt ( posAdj ) and
2897+ (
28932898 exists ( string derefChainBorrow |
28942899 FunctionCallMatchingInput:: decodeDerefChainBorrow ( derefChainBorrow , derefChain , borrow )
28952900 |
2896- result = FunctionCallMatching:: inferAccessType ( a , derefChainBorrow , apos , path0 )
2901+ result = FunctionCallMatching:: inferAccessType ( a , derefChainBorrow , posAdj , path0 )
28972902 or
2898- a .hasUnknownTypeAt ( derefChainBorrow , apos , path0 ) and
2903+ a .hasUnknownTypeAt ( derefChainBorrow , posAdj , path0 ) and
28992904 result = TUnknownType ( )
29002905 )
29012906 or
2902- a .hasUnknownTypeAt ( apos , path0 ) and
2907+ a .hasUnknownTypeAt ( posAdj , path0 ) and
29032908 result = TUnknownType ( ) and
29042909 derefChain .isEmpty ( ) and
29052910 borrow .isNoBorrow ( )
@@ -2908,7 +2913,7 @@ private Type inferFunctionCallType0(
29082913 if
29092914 // index expression `x[i]` desugars to `*x.index(i)`, so we must account for
29102915 // the implicit deref
2911- apos .isReturn ( ) and
2916+ posAdj .isReturn ( ) and
29122917 a instanceof IndexExpr
29132918 then path0 .isCons ( getRefTypeParameter ( _) , path )
29142919 else path = path0
@@ -2917,8 +2922,10 @@ private Type inferFunctionCallType0(
29172922
29182923pragma [ nomagic]
29192924private Type inferFunctionCallTypeNonSelf ( AstNode n , FunctionPosition pos , TypePath path ) {
2920- result = inferFunctionCallType0 ( _, pos , n , _, _, path ) and
2921- not pos .isSelf ( )
2925+ exists ( FunctionCallMatchingInput:: Access a |
2926+ result = inferFunctionCallType0 ( a , pos , n , _, _, path ) and
2927+ not a .( AssocFunctionResolution:: AssocFunctionCall ) .hasReceiverPos ( pos )
2928+ )
29222929}
29232930
29242931/**
@@ -2929,11 +2936,13 @@ private Type inferFunctionCallTypeNonSelf(AstNode n, FunctionPosition pos, TypeP
29292936 * empty, at which point the inferred type can be applied back to `n`.
29302937 */
29312938pragma [ nomagic]
2932- private Type inferMethodCallTypeSelf ( MethodCall mc , AstNode n , DerefChain derefChain , TypePath path ) {
2933- exists ( FunctionCallMatchingInput:: AccessPosition apos , BorrowKind borrow , TypePath path0 |
2934- result = inferFunctionCallType0 ( mc , apos , n , derefChain , borrow , path0 ) and
2935- apos .isSelf ( )
2939+ private Type inferFunctionCallTypeSelf (
2940+ MethodCall mc , AstNode n , DerefChain derefChain , TypePath path
2941+ ) {
2942+ exists ( FunctionPosition posAdj , BorrowKind borrow , TypePath path0 |
2943+ result = inferFunctionCallType0 ( mc , posAdj , n , derefChain , borrow , path0 ) //and
29362944 |
2945+ posAdj .asPosition ( ) = 0 and
29372946 borrow .isNoBorrow ( ) and
29382947 path = path0
29392948 or
@@ -2949,7 +2958,7 @@ private Type inferMethodCallTypeSelf(MethodCall mc, AstNode n, DerefChain derefC
29492958 DerefChain derefChain0 , Type t0 , TypePath path0 , DerefImplItemNode impl , Type selfParamType ,
29502959 TypePath selfPath
29512960 |
2952- t0 = inferMethodCallTypeSelf ( mc , n , derefChain0 , path0 ) and
2961+ t0 = inferFunctionCallTypeSelf ( mc , n , derefChain0 , path0 ) and
29532962 derefChain0 .isCons ( impl , derefChain ) and
29542963 selfParamType = impl .resolveSelfTypeAt ( selfPath )
29552964 |
@@ -2966,21 +2975,29 @@ private Type inferMethodCallTypeSelf(MethodCall mc, AstNode n, DerefChain derefC
29662975 )
29672976}
29682977
2969- private Type inferMethodCallTypePreCheck ( AstNode n , FunctionPosition pos , TypePath path ) {
2978+ private Type inferFunctionCallTypePreCheck ( AstNode n , FunctionPosition pos , TypePath path ) {
29702979 result = inferFunctionCallTypeNonSelf ( n , pos , path )
29712980 or
2972- exists ( MethodCall mc |
2973- result = inferMethodCallTypeSelf ( mc , n , DerefChain:: nil ( ) , path ) and
2974- if mc instanceof CallExpr then pos .asPosition ( ) = 0 else pos .isSelf ( )
2981+ exists ( FunctionCallMatchingInput:: Access a |
2982+ result = inferFunctionCallTypeSelf ( a , n , DerefChain:: nil ( ) , path ) and
2983+ if a .( AssocFunctionResolution:: AssocFunctionCall ) .hasReceiver ( )
2984+ then pos .isSelf ( )
2985+ else pos .asPosition ( ) = 0
29752986 )
2987+ // result = inferFunctionCallTypeNonSelf(n, pos, path)
2988+ // or
2989+ // exists(MethodCall mc |
2990+ // result = inferMethodCallTypeSelf(mc, n, DerefChain::nil(), path) and
2991+ // if mc instanceof CallExpr then pos.asPosition() = 0 else pos.isSelf()
2992+ // )
29762993}
29772994
29782995/**
29792996 * Gets the type of `n` at `path`, where `n` is either a method call or an
29802997 * argument/receiver of a method call.
29812998 */
2982- private predicate inferMethodCallType =
2983- ContextTyping:: CheckContextTyping< inferMethodCallTypePreCheck / 3 > :: check / 2 ;
2999+ private predicate inferFunctionCallType =
3000+ ContextTyping:: CheckContextTyping< inferFunctionCallTypePreCheck / 3 > :: check / 2 ;
29843001
29853002abstract private class TupleLikeConstructor extends Addressable {
29863003 final TypeParameter getTypeParameter ( TypeParameterPosition ppos ) {
@@ -3218,14 +3235,14 @@ private module OperationMatchingInput implements MatchingInputSig {
32183235 }
32193236
32203237 pragma [ nomagic]
3221- private predicate borrowsAt ( DeclarationPosition pos ) {
3238+ private predicate borrowsAt ( FunctionPosition posAdj ) {
32223239 exists ( TraitItemNode t , string path , string method |
32233240 this .getSelfOrImpl ( ) = t .getAssocItem ( method ) and
32243241 path = t .getCanonicalPath ( _) and
32253242 exists ( int borrows | OperationImpl:: isOverloaded ( _, _, path , method , borrows ) |
3226- pos . isSelf ( ) and borrows >= 1
3243+ posAdj . asPosition ( ) = 0 and borrows >= 1
32273244 or
3228- pos .asPosition ( ) = 0 and
3245+ posAdj .asPosition ( ) = 1 and
32293246 borrows >= 2
32303247 )
32313248 )
@@ -3234,13 +3251,13 @@ private module OperationMatchingInput implements MatchingInputSig {
32343251 pragma [ nomagic]
32353252 private predicate derefsReturn ( ) { this .getSelfOrImpl ( ) = any ( DerefTrait t ) .getDerefFunction ( ) }
32363253
3237- Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
3254+ Type getDeclaredType ( FunctionPosition posAdj , TypePath path ) {
32383255 exists ( TypePath path0 |
3239- result = super .getDeclaredType ( dpos , path0 ) and
3256+ result = super .getDeclaredType ( posAdj , path0 ) and
32403257 if
3241- this .borrowsAt ( dpos )
3258+ this .borrowsAt ( posAdj )
32423259 or
3243- dpos .isReturn ( ) and this .derefsReturn ( )
3260+ posAdj .isReturn ( ) and this .derefsReturn ( )
32443261 then path0 .isCons ( getRefTypeParameter ( _) , path )
32453262 else path0 = path
32463263 )
@@ -3251,8 +3268,8 @@ private module OperationMatchingInput implements MatchingInputSig {
32513268 Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) { none ( ) }
32523269
32533270 pragma [ nomagic]
3254- Type getInferredType ( FunctionPosition pos , TypePath path ) {
3255- result = inferType ( this .getNodeAt ( pos . getFunctionCallAdjusted ( ) ) , path )
3271+ Type getInferredType ( FunctionPosition posAdj , TypePath path ) {
3272+ result = inferType ( this .getNodeAt ( posAdj ) , path )
32563273 }
32573274
32583275 Declaration getTarget ( ) {
@@ -3270,7 +3287,7 @@ private Type inferOperationType0(AstNode n, FunctionPosition pos, TypePath path)
32703287 exists ( OperationMatchingInput:: Access a , FunctionPosition posAdj |
32713288 n = a .getNodeAt ( posAdj ) and
32723289 posAdj = pos .getFunctionCallAdjusted ( ) and
3273- result = OperationMatching:: inferAccessType ( a , pos , path )
3290+ result = OperationMatching:: inferAccessType ( a , posAdj , path )
32743291 )
32753292}
32763293
@@ -4091,7 +4108,7 @@ private module Cached {
40914108 or
40924109 result = inferStructExprType ( n , path )
40934110 or
4094- result = inferMethodCallType ( n , path )
4111+ result = inferFunctionCallType ( n , path )
40954112 or
40964113 result = inferNonMethodCallType ( n , path )
40974114 or
@@ -4134,8 +4151,8 @@ private module Debug {
41344151 Locatable getRelevantLocatable ( ) {
41354152 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
41364153 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
4137- filepath .matches ( "%/overloading .rs" ) and
4138- startline = 399
4154+ filepath .matches ( "%/main .rs" ) and
4155+ startline = 2050
41394156 )
41404157 }
41414158
@@ -4161,9 +4178,9 @@ private module Debug {
41614178 t = self .getTypeAt ( path )
41624179 }
41634180
4164- predicate debugInferMethodCallType ( AstNode n , TypePath path , Type t ) {
4181+ predicate debugInferFunctionCallType ( AstNode n , TypePath path , Type t ) {
41654182 n = getRelevantLocatable ( ) and
4166- t = inferMethodCallType ( n , path )
4183+ t = inferFunctionCallType ( n , path )
41674184 }
41684185
41694186 predicate debugInferNonMethodCallType ( AstNode n , TypePath path , Type t ) {
0 commit comments