@@ -871,11 +871,6 @@ private module FunctionOverloading {
871871 Impl impl , TraitItemNode trait , Type rootType , TypeMention selfTy
872872 ) {
873873 trait = impl .( ImplItemNode ) .resolveTraitTy ( ) and
874- // If `impl` has an expansion from a macro attribute, then it's been
875- // superseded by the output of the expansion (and usually the expansion
876- // contains the same `impl` block so considering both would give spurious
877- // siblings).
878- not exists ( impl .getAttributeMacroExpansion ( ) ) and
879874 selfTy = impl .getSelfTy ( ) and
880875 rootType = selfTy .resolveType ( )
881876 }
@@ -1393,7 +1388,8 @@ private module MethodCallResolution {
13931388 Function m , string name , int arity , ImplItemNode i , FunctionType selfType , TypePath blanketPath ,
13941389 TypeParam blanketTypeParam
13951390 ) {
1396- methodInfoTypeParam ( m , name , arity , i , selfType , blanketPath , blanketTypeParam ) and
1391+ methodInfo ( m , name , arity , i , selfType , _, _) and
1392+ TTypeParamTypeParameter ( blanketTypeParam ) = selfType .getTypeAt ( blanketPath ) and
13971393 blanketTypeParam = i .getBlanketImplementationTypeParam ( )
13981394 }
13991395
@@ -1702,7 +1698,7 @@ private module MethodCallResolution {
17021698 }
17031699
17041700 pragma [ nomagic]
1705- predicate hasInfo (
1701+ predicate hasSignature (
17061702 MethodCall mc , TypePath strippedTypePath , Type strippedType , string name , int arity
17071703 ) {
17081704 strippedType = this .getTypeAt ( strippedTypePath ) and
@@ -1728,7 +1724,7 @@ private module MethodCallResolution {
17281724 pragma [ nomagic]
17291725 predicate hasNoInherentTarget ( ) {
17301726 exists ( TypePath strippedTypePath , Type strippedType , string name , int arity |
1731- this .hasInfo ( _, strippedTypePath , strippedType , name , arity ) and
1727+ this .hasSignature ( _, strippedTypePath , strippedType , name , arity ) and
17321728 forall ( Impl i |
17331729 methodInfoNonBlanket ( _, name , arity , i , _, strippedTypePath , strippedType ) and
17341730 not i .hasTrait ( )
@@ -1800,7 +1796,7 @@ private module MethodCallResolution {
18001796 MethodCallCand mcc , Function m , TypePath blanketPath , TypeParam blanketTypeParam
18011797 ) {
18021798 exists ( MethodCall mc , string name , int arity |
1803- mcc .hasInfo ( mc , _, _, name , arity ) and
1799+ mcc .hasSignature ( mc , _, _, name , arity ) and
18041800 methodCallBlanketCandidate ( mc , m , _, _, blanketPath , blanketTypeParam )
18051801 )
18061802 }
@@ -1821,7 +1817,7 @@ private module MethodCallResolution {
18211817 MethodCall mc , Function m , string name , int arity , TypePath strippedTypePath ,
18221818 Type strippedType
18231819 |
1824- mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity )
1820+ mcc .hasSignature ( mc , strippedTypePath , strippedType , name , arity )
18251821 |
18261822 methodCallNonBlanketCandidate ( mc , m , abs , constraint , strippedTypePath , strippedType )
18271823 or
@@ -2035,7 +2031,21 @@ private Type inferMethodCallExprType(AstNode n, TypePath path) {
20352031 )
20362032}
20372033
2038- /** Provides logic for resolving function calls. */
2034+ /**
2035+ * Provides logic for resolving function calls.
2036+ *
2037+ * We distinguish between three cases:
2038+ *
2039+ * 1. The qualifier of the function call is _not_ a trait, and the function call
2040+ * can be resolved using path resolution. In this case we use the resolved
2041+ * function directly, we do not even check the receiver type in case the resolved
2042+ * function is a method.
2043+ *
2044+ * 2. The qualifier of the function call _is_ a trait, and the function call can be
2045+ * resolved using path resolution. In this case we use the resolved function
2046+ * directly, we do not even check the receiver type in case the resolved
2047+ * function is a method.
2048+ */
20392049private module FunctionCallResolution {
20402050 private import FunctionOverloading
20412051
@@ -2068,8 +2078,22 @@ private module FunctionCallResolution {
20682078
20692079 /** A function call, `f(x)`. */
20702080 final class FunctionCall extends CallExpr {
2071- private ItemNode getPathResolutionResolvedFunction ( ) {
2072- result = CallExprImpl:: getResolvedFunction ( this )
2081+ pragma [ nomagic]
2082+ predicate hasSignature ( string name , int arity ) {
2083+ name = CallExprImpl:: getFunctionPath ( this ) .getText ( ) and
2084+ arity = this .getNumberOfArgs ( )
2085+ }
2086+
2087+ /**
2088+ * Gets the item that this function call resolves to using path resolution,
2089+ * if any.
2090+ */
2091+ ItemNode getPathResolutionResolvedFunction ( ) {
2092+ exists ( string name , int arity |
2093+ this .hasSignature ( name , arity ) and
2094+ result = CallExprImpl:: getResolvedFunction ( this ) and
2095+ result .( FunctionCallMatchingInput:: Declaration ) .getArity ( ) = arity
2096+ )
20732097 }
20742098
20752099 pragma [ nomagic]
@@ -2078,7 +2102,7 @@ private module FunctionCallResolution {
20782102 }
20792103
20802104 pragma [ nomagic]
2081- predicate hasInfo (
2105+ predicate hasSignature (
20822106 TypePath strippedTypePath , Type strippedType , TraitItemNode trait , Function resolved
20832107 ) {
20842108 this .getTypeAt ( strippedTypePath ) = strippedType and
@@ -2089,9 +2113,8 @@ private module FunctionCallResolution {
20892113
20902114 pragma [ nomagic]
20912115 private Function getATargetMethodCand ( ) {
2092- exists ( TraitItemNode trait , ImplOrTraitItemNode i , FunctionType self |
2093- FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , trait , i , self ,
2094- result ) and
2116+ exists ( ImplOrTraitItemNode i , FunctionType self |
2117+ FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , i , self , result ) and
20952118 IsInstantiationOf< FunctionCall , FunctionType , FunctionMethodCallIsInstantiationOfInput > :: isInstantiationOf ( this ,
20962119 i , self )
20972120 )
@@ -2156,6 +2179,38 @@ private module FunctionCallResolution {
21562179 }
21572180 }
21582181
2182+ private module SatisfiesBlanketConstraintInput implements
2183+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< FunctionCall >
2184+ {
2185+ pragma [ nomagic]
2186+ private predicate hasBlanketCandidate (
2187+ FunctionCall call , Trait trait , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2188+ ) {
2189+ not exists ( call .getPathResolutionResolvedFunction ( ) ) and
2190+ exists ( string name , int arity , ImplItemNode impl |
2191+ call .hasSignature ( name , arity + 1 ) and
2192+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , _, blanketPath ,
2193+ blanketTypeParam ) and
2194+ trait = impl .resolveTraitTy ( )
2195+ )
2196+ }
2197+
2198+ pragma [ nomagic]
2199+ private predicate functionCallTraitCandidate ( Element mc , Trait trait ) {
2200+ hasBlanketCandidate ( mc , trait , _, _, _)
2201+ }
2202+
2203+ pragma [ nomagic]
2204+ predicate hasBlanketCandidate (
2205+ FunctionCall call , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2206+ ) {
2207+ exists ( Trait trait |
2208+ hasBlanketCandidate ( call , trait , m , blanketPath , blanketTypeParam ) and
2209+ TraitIsVisible< functionCallTraitCandidate / 2 > :: traitIsVisible ( call , trait )
2210+ )
2211+ }
2212+ }
2213+
21592214 /**
21602215 * A configuration for matching the type of the first argument in a function call
21612216 * against the type of a `self` parameter.
@@ -2195,15 +2250,21 @@ private module FunctionCallResolution {
21952250
21962251 pragma [ nomagic]
21972252 additional predicate potentialInstantiationOf (
2198- FunctionCall call , TraitItemNode trait , ImplOrTraitItemNode i , FunctionType selfType ,
2199- Function f
2253+ FunctionCall call , ImplOrTraitItemNode i , FunctionType selfType , Function f
22002254 ) {
2201- exists ( Function resolved , TypePath strippedTypePath , Type strippedType |
2202- call .hasInfo ( strippedTypePath , strippedType , trait , resolved )
2203- |
2204- methodInfo ( strippedTypePath , strippedType , trait , f , resolved )
2255+ (
2256+ exists (
2257+ TraitItemNode trait , Function resolved , TypePath strippedTypePath , Type strippedType
2258+ |
2259+ call .hasSignature ( strippedTypePath , strippedType , trait , resolved )
2260+ |
2261+ methodInfo ( strippedTypePath , strippedType , trait , f , resolved )
2262+ or
2263+ methodInfoTypeParam ( strippedTypePath , trait , f , resolved )
2264+ )
22052265 or
2206- methodInfoTypeParam ( strippedTypePath , trait , f , resolved )
2266+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraint< FunctionCall , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( call ,
2267+ f )
22072268 ) and
22082269 MethodCallResolution:: methodInfo ( f , _, _, i , selfType , _, _)
22092270 }
@@ -2212,7 +2273,7 @@ private module FunctionCallResolution {
22122273 predicate potentialInstantiationOf (
22132274 FunctionCall call , TypeAbstraction abs , FunctionType constraint
22142275 ) {
2215- potentialInstantiationOf ( call , _ , abs , constraint , _)
2276+ potentialInstantiationOf ( call , abs , constraint , _)
22162277 }
22172278
22182279 predicate relevantTypeMention ( FunctionType constraint ) {
@@ -2236,6 +2297,13 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
22362297
22372298 abstract Type getReturnType ( TypePath path ) ;
22382299
2300+ int getArity ( ) {
2301+ result =
2302+ count ( DeclarationPosition dpos |
2303+ dpos .isPositional ( ) and exists ( this .getParameterType ( dpos , _) )
2304+ )
2305+ }
2306+
22392307 Type getDeclaredType ( DeclarationPosition dpos , TypePath path ) {
22402308 result = this .getParameterType ( dpos , path )
22412309 or
@@ -2423,7 +2491,7 @@ private module OperationResolution {
24232491 Type getTypeAt ( TypePath path ) { result = substituteLookupTraits ( this .getTypeAt0 ( path ) ) }
24242492
24252493 pragma [ nomagic]
2426- predicate hasInfo (
2494+ predicate hasSignature (
24272495 TypePath strippedTypePath , Type strippedType , Trait trait , string name , int arity
24282496 ) {
24292497 name = this .( Call ) .getMethodName ( ) and
@@ -2461,18 +2529,32 @@ private module OperationResolution {
24612529 }
24622530 }
24632531
2532+ private module SatisfiesBlanketConstraintInput implements
2533+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< Op >
2534+ {
2535+ pragma [ nomagic]
2536+ predicate hasBlanketCandidate (
2537+ Op op , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2538+ ) {
2539+ exists ( Trait trait , string name , int arity , ImplItemNode impl |
2540+ op .hasSignature ( _, _, trait , name , arity ) and
2541+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , _, blanketPath ,
2542+ blanketTypeParam ) and
2543+ trait = impl .resolveTraitTy ( )
2544+ )
2545+ }
2546+ }
2547+
24642548 private module OperationIsInstantiationOfInput implements
24652549 IsInstantiationOfInputSig< Op , FunctionType >
24662550 {
2467- // todo
24682551 bindingset [ strippedTypePath]
24692552 private predicate methodInfoNonBlanket (
24702553 TypeAbstraction abs , FunctionType constraint , Trait trait , string name , int arity ,
24712554 TypePath strippedTypePath , Type strippedType
24722555 ) {
24732556 MethodCallResolution:: methodInfoNonBlanket ( _, name , arity , abs , constraint , strippedTypePath ,
24742557 strippedType ) and
2475- not abs .( ImplItemNode ) .isBlanketImplementation ( ) and
24762558 (
24772559 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
24782560 or
@@ -2483,9 +2565,15 @@ private module OperationResolution {
24832565 pragma [ nomagic]
24842566 predicate potentialInstantiationOf ( Op op , TypeAbstraction abs , FunctionType constraint ) {
24852567 exists ( Trait trait , string name , int arity , TypePath strippedTypePath , Type strippedType |
2486- op .hasInfo ( strippedTypePath , strippedType , trait , name , arity ) and
2568+ op .hasSignature ( strippedTypePath , strippedType , trait , name , arity ) and
24872569 methodInfoNonBlanket ( abs , constraint , trait , name , arity , strippedTypePath , strippedType )
24882570 )
2571+ or
2572+ exists ( Function m |
2573+ MethodCallResolution:: methodInfoBlanket ( m , _, _, abs , constraint , _, _) and
2574+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraint< Op , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( op ,
2575+ m )
2576+ )
24892577 }
24902578
24912579 predicate relevantTypeMention ( FunctionType constraint ) {
0 commit comments