@@ -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,7 +2078,17 @@ private module FunctionCallResolution {
20682078
20692079 /** A function call, `f(x)`. */
20702080 final class FunctionCall extends CallExpr {
2071- private ItemNode getPathResolutionResolvedFunction ( ) {
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 ( ) {
20722092 result = CallExprImpl:: getResolvedFunction ( this )
20732093 }
20742094
@@ -2078,7 +2098,7 @@ private module FunctionCallResolution {
20782098 }
20792099
20802100 pragma [ nomagic]
2081- predicate hasInfo (
2101+ predicate hasSignature (
20822102 TypePath strippedTypePath , Type strippedType , TraitItemNode trait , Function resolved
20832103 ) {
20842104 this .getTypeAt ( strippedTypePath ) = strippedType and
@@ -2089,9 +2109,8 @@ private module FunctionCallResolution {
20892109
20902110 pragma [ nomagic]
20912111 private Function getATargetMethodCand ( ) {
2092- exists ( TraitItemNode trait , ImplOrTraitItemNode i , FunctionType self |
2093- FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , trait , i , self ,
2094- result ) and
2112+ exists ( ImplOrTraitItemNode i , FunctionType self |
2113+ FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , i , self , result ) and
20952114 IsInstantiationOf< FunctionCall , FunctionType , FunctionMethodCallIsInstantiationOfInput > :: isInstantiationOf ( this ,
20962115 i , self )
20972116 )
@@ -2156,6 +2175,38 @@ private module FunctionCallResolution {
21562175 }
21572176 }
21582177
2178+ private module SatisfiesBlanketConstraintInput implements
2179+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< FunctionCall >
2180+ {
2181+ pragma [ nomagic]
2182+ private predicate hasBlanketCandidate (
2183+ FunctionCall call , Trait trait , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2184+ ) {
2185+ not exists ( call .getPathResolutionResolvedFunction ( ) ) and
2186+ exists ( string name , int arity , ImplItemNode impl |
2187+ call .hasSignature ( name , arity + 1 ) and
2188+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , _, blanketPath ,
2189+ blanketTypeParam ) and
2190+ trait = impl .resolveTraitTy ( )
2191+ )
2192+ }
2193+
2194+ pragma [ nomagic]
2195+ private predicate functionCallTraitCandidate ( Element mc , Trait trait ) {
2196+ hasBlanketCandidate ( mc , trait , _, _, _)
2197+ }
2198+
2199+ pragma [ nomagic]
2200+ predicate hasBlanketCandidate (
2201+ FunctionCall call , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2202+ ) {
2203+ exists ( Trait trait |
2204+ hasBlanketCandidate ( call , trait , m , blanketPath , blanketTypeParam ) and
2205+ TraitIsVisible< functionCallTraitCandidate / 2 > :: traitIsVisible ( call , trait )
2206+ )
2207+ }
2208+ }
2209+
21592210 /**
21602211 * A configuration for matching the type of the first argument in a function call
21612212 * against the type of a `self` parameter.
@@ -2195,15 +2246,21 @@ private module FunctionCallResolution {
21952246
21962247 pragma [ nomagic]
21972248 additional predicate potentialInstantiationOf (
2198- FunctionCall call , TraitItemNode trait , ImplOrTraitItemNode i , FunctionType selfType ,
2199- Function f
2249+ FunctionCall call , ImplOrTraitItemNode i , FunctionType selfType , Function f
22002250 ) {
2201- exists ( Function resolved , TypePath strippedTypePath , Type strippedType |
2202- call .hasInfo ( strippedTypePath , strippedType , trait , resolved )
2203- |
2204- methodInfo ( strippedTypePath , strippedType , trait , f , resolved )
2251+ (
2252+ exists (
2253+ TraitItemNode trait , Function resolved , TypePath strippedTypePath , Type strippedType
2254+ |
2255+ call .hasSignature ( strippedTypePath , strippedType , trait , resolved )
2256+ |
2257+ methodInfo ( strippedTypePath , strippedType , trait , f , resolved )
2258+ or
2259+ methodInfoTypeParam ( strippedTypePath , trait , f , resolved )
2260+ )
22052261 or
2206- methodInfoTypeParam ( strippedTypePath , trait , f , resolved )
2262+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraint< FunctionCall , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( call ,
2263+ f )
22072264 ) and
22082265 MethodCallResolution:: methodInfo ( f , _, _, i , selfType , _, _)
22092266 }
@@ -2212,7 +2269,7 @@ private module FunctionCallResolution {
22122269 predicate potentialInstantiationOf (
22132270 FunctionCall call , TypeAbstraction abs , FunctionType constraint
22142271 ) {
2215- potentialInstantiationOf ( call , _ , abs , constraint , _)
2272+ potentialInstantiationOf ( call , abs , constraint , _)
22162273 }
22172274
22182275 predicate relevantTypeMention ( FunctionType constraint ) {
@@ -2423,7 +2480,7 @@ private module OperationResolution {
24232480 Type getTypeAt ( TypePath path ) { result = substituteLookupTraits ( this .getTypeAt0 ( path ) ) }
24242481
24252482 pragma [ nomagic]
2426- predicate hasInfo (
2483+ predicate hasSignature (
24272484 TypePath strippedTypePath , Type strippedType , Trait trait , string name , int arity
24282485 ) {
24292486 name = this .( Call ) .getMethodName ( ) and
@@ -2461,18 +2518,39 @@ private module OperationResolution {
24612518 }
24622519 }
24632520
2521+ private module SatisfiesBlanketConstraintInput implements
2522+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< Op >
2523+ {
2524+ pragma [ nomagic]
2525+ private predicate methodInfoBlanket (
2526+ Function m , string name , int arity , ImplItemNode impl , Trait trait , TypePath blanketPath ,
2527+ TypeParam blanketTypeParam
2528+ ) {
2529+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , _, blanketPath , blanketTypeParam ) and
2530+ trait = impl .resolveTraitTy ( )
2531+ }
2532+
2533+ pragma [ nomagic]
2534+ predicate hasBlanketCandidate (
2535+ Op op , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2536+ ) {
2537+ exists ( Trait trait , string name , int arity , ImplItemNode impl |
2538+ op .hasSignature ( _, _, trait , name , arity ) and
2539+ methodInfoBlanket ( m , name , arity , impl , trait , blanketPath , blanketTypeParam )
2540+ )
2541+ }
2542+ }
2543+
24642544 private module OperationIsInstantiationOfInput implements
24652545 IsInstantiationOfInputSig< Op , FunctionType >
24662546 {
2467- // todo
24682547 bindingset [ strippedTypePath]
24692548 private predicate methodInfoNonBlanket (
24702549 TypeAbstraction abs , FunctionType constraint , Trait trait , string name , int arity ,
24712550 TypePath strippedTypePath , Type strippedType
24722551 ) {
24732552 MethodCallResolution:: methodInfoNonBlanket ( _, name , arity , abs , constraint , strippedTypePath ,
24742553 strippedType ) and
2475- not abs .( ImplItemNode ) .isBlanketImplementation ( ) and
24762554 (
24772555 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
24782556 or
@@ -2483,9 +2561,15 @@ private module OperationResolution {
24832561 pragma [ nomagic]
24842562 predicate potentialInstantiationOf ( Op op , TypeAbstraction abs , FunctionType constraint ) {
24852563 exists ( Trait trait , string name , int arity , TypePath strippedTypePath , Type strippedType |
2486- op .hasInfo ( strippedTypePath , strippedType , trait , name , arity ) and
2564+ op .hasSignature ( strippedTypePath , strippedType , trait , name , arity ) and
24872565 methodInfoNonBlanket ( abs , constraint , trait , name , arity , strippedTypePath , strippedType )
24882566 )
2567+ or
2568+ exists ( Function m |
2569+ MethodCallResolution:: methodInfoBlanket ( m , _, _, abs , constraint , _, _) and
2570+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraint< Op , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( op ,
2571+ m )
2572+ )
24892573 }
24902574
24912575 predicate relevantTypeMention ( FunctionType constraint ) {
0 commit comments