@@ -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 }
@@ -1380,8 +1375,8 @@ private module MethodCallResolution {
13801375
13811376 /**
13821377 * Holds if method `m` with the name `name` and the arity `arity` exists in
1383- * [blanket implementation][1] `i` and the type of the `self` parameter is
1384- * `selfType`.
1378+ * [blanket implementation][1] `impl` of `trait`, and the type of the `self`
1379+ * parameter is `selfType`.
13851380 *
13861381 * `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which
13871382 * is the type parameter used in the blanket implementation.
@@ -1390,11 +1385,13 @@ private module MethodCallResolution {
13901385 */
13911386 pragma [ nomagic]
13921387 predicate methodInfoBlanket (
1393- Function m , string name , int arity , ImplItemNode i , FunctionType selfType , TypePath blanketPath ,
1394- TypeParam blanketTypeParam
1388+ Function m , string name , int arity , ImplItemNode impl , Trait trait , FunctionType selfType ,
1389+ TypePath blanketPath , TypeParam blanketTypeParam
13951390 ) {
1396- methodInfoTypeParam ( m , name , arity , i , selfType , blanketPath , blanketTypeParam ) and
1397- blanketTypeParam = i .getBlanketImplementationTypeParam ( )
1391+ methodInfo ( m , name , arity , impl , selfType , _, _) and
1392+ TTypeParamTypeParameter ( blanketTypeParam ) = selfType .getTypeAt ( blanketPath ) and
1393+ blanketTypeParam = impl .getBlanketImplementationTypeParam ( ) and
1394+ trait = impl .resolveTraitTy ( )
13981395 }
13991396
14001397 pragma [ nomagic]
@@ -1479,7 +1476,7 @@ private module MethodCallResolution {
14791476 ) {
14801477 exists ( string name , int arity |
14811478 mc .hasNameAndArity ( name , arity ) and
1482- methodInfoBlanket ( m , name , arity , i , self , blanketPath , blanketTypeParam )
1479+ methodInfoBlanket ( m , name , arity , i , _ , self , blanketPath , blanketTypeParam )
14831480 |
14841481 methodCallVisibleImplTraitCandidate ( mc , i )
14851482 or
@@ -1702,7 +1699,7 @@ private module MethodCallResolution {
17021699 }
17031700
17041701 pragma [ nomagic]
1705- predicate hasInfo (
1702+ predicate hasSignature (
17061703 MethodCall mc , TypePath strippedTypePath , Type strippedType , string name , int arity
17071704 ) {
17081705 strippedType = this .getTypeAt ( strippedTypePath ) and
@@ -1728,7 +1725,7 @@ private module MethodCallResolution {
17281725 pragma [ nomagic]
17291726 predicate hasNoInherentTarget ( ) {
17301727 exists ( TypePath strippedTypePath , Type strippedType , string name , int arity |
1731- this .hasInfo ( _, strippedTypePath , strippedType , name , arity ) and
1728+ this .hasSignature ( _, strippedTypePath , strippedType , name , arity ) and
17321729 forall ( Impl i |
17331730 methodInfoNonBlanket ( _, name , arity , i , _, strippedTypePath , strippedType ) and
17341731 not i .hasTrait ( )
@@ -1800,7 +1797,7 @@ private module MethodCallResolution {
18001797 MethodCallCand mcc , Function m , TypePath blanketPath , TypeParam blanketTypeParam
18011798 ) {
18021799 exists ( MethodCall mc , string name , int arity |
1803- mcc .hasInfo ( mc , _, _, name , arity ) and
1800+ mcc .hasSignature ( mc , _, _, name , arity ) and
18041801 methodCallBlanketCandidate ( mc , m , _, _, blanketPath , blanketTypeParam )
18051802 )
18061803 }
@@ -1821,7 +1818,7 @@ private module MethodCallResolution {
18211818 MethodCall mc , Function m , string name , int arity , TypePath strippedTypePath ,
18221819 Type strippedType
18231820 |
1824- mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity )
1821+ mcc .hasSignature ( mc , strippedTypePath , strippedType , name , arity )
18251822 |
18261823 methodCallNonBlanketCandidate ( mc , m , abs , constraint , strippedTypePath , strippedType )
18271824 or
@@ -2035,7 +2032,21 @@ private Type inferMethodCallExprType(AstNode n, TypePath path) {
20352032 )
20362033}
20372034
2038- /** Provides logic for resolving function calls. */
2035+ /**
2036+ * Provides logic for resolving function calls.
2037+ *
2038+ * We distinguish between three cases:
2039+ *
2040+ * 1. The qualifier of the function call is _not_ a trait, and the function call
2041+ * can be resolved using path resolution. In this case we use the resolved
2042+ * function directly, we do not even check the receiver type in case the resolved
2043+ * function is a method.
2044+ *
2045+ * 2. The qualifier of the function call _is_ a trait, and the function call can be
2046+ * resolved using path resolution. In this case we use the resolved function
2047+ * directly, we do not even check the receiver type in case the resolved
2048+ * function is a method.
2049+ */
20392050private module FunctionCallResolution {
20402051 private import FunctionOverloading
20412052
@@ -2068,7 +2079,11 @@ private module FunctionCallResolution {
20682079
20692080 /** A function call, `f(x)`. */
20702081 final class FunctionCall extends CallExpr {
2071- private ItemNode getPathResolutionResolvedFunction ( ) {
2082+ /**
2083+ * Gets the item that this function call resolves to using path resolution,
2084+ * if any.
2085+ */
2086+ ItemNode getPathResolutionResolvedFunction ( ) {
20722087 result = CallExprImpl:: getResolvedFunction ( this )
20732088 }
20742089
@@ -2078,7 +2093,7 @@ private module FunctionCallResolution {
20782093 }
20792094
20802095 pragma [ nomagic]
2081- predicate hasInfo (
2096+ predicate hasSignature (
20822097 TypePath strippedTypePath , Type strippedType , TraitItemNode trait , Function resolved
20832098 ) {
20842099 this .getTypeAt ( strippedTypePath ) = strippedType and
@@ -2089,9 +2104,8 @@ private module FunctionCallResolution {
20892104
20902105 pragma [ nomagic]
20912106 private Function getATargetMethodCand ( ) {
2092- exists ( TraitItemNode trait , ImplOrTraitItemNode i , FunctionType self |
2093- FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , trait , i , self ,
2094- result ) and
2107+ exists ( ImplOrTraitItemNode i , FunctionType self |
2108+ FunctionMethodCallIsInstantiationOfInput:: potentialInstantiationOf ( this , i , self , result ) and
20952109 IsInstantiationOf< FunctionCall , FunctionType , FunctionMethodCallIsInstantiationOfInput > :: isInstantiationOf ( this ,
20962110 i , self )
20972111 )
@@ -2156,6 +2170,43 @@ private module FunctionCallResolution {
21562170 }
21572171 }
21582172
2173+ private module SatisfiesBlanketConstraintInput implements
2174+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< FunctionCall >
2175+ {
2176+ pragma [ nomagic]
2177+ private predicate hasSignature ( FunctionCall call , string name , int arity ) {
2178+ name = CallExprImpl:: getFunctionPath ( call ) .getText ( ) and
2179+ arity = call .getNumberOfArgs ( ) - 1
2180+ }
2181+
2182+ pragma [ nomagic]
2183+ private predicate hasBlanketCandidate (
2184+ FunctionCall call , Trait trait , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2185+ ) {
2186+ not exists ( call .getPathResolutionResolvedFunction ( ) ) and
2187+ exists ( string name , int arity , ImplItemNode impl |
2188+ hasSignature ( call , name , arity ) and
2189+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , trait , _, blanketPath ,
2190+ blanketTypeParam )
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,31 @@ private module OperationResolution {
24612518 }
24622519 }
24632520
2521+ private module SatisfiesBlanketConstraintInput implements
2522+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraintInputSig< Op >
2523+ {
2524+ pragma [ nomagic]
2525+ predicate hasBlanketCandidate (
2526+ Op op , Function m , TypePath blanketPath , TypeParam blanketTypeParam
2527+ ) {
2528+ exists ( Trait trait , string name , int arity , ImplItemNode impl |
2529+ op .hasSignature ( _, _, trait , name , arity ) and
2530+ MethodCallResolution:: methodInfoBlanket ( m , name , arity , impl , trait , _, blanketPath ,
2531+ blanketTypeParam )
2532+ )
2533+ }
2534+ }
2535+
24642536 private module OperationIsInstantiationOfInput implements
24652537 IsInstantiationOfInputSig< Op , FunctionType >
24662538 {
2467- // todo
24682539 bindingset [ strippedTypePath]
24692540 private predicate methodInfoNonBlanket (
24702541 TypeAbstraction abs , FunctionType constraint , Trait trait , string name , int arity ,
24712542 TypePath strippedTypePath , Type strippedType
24722543 ) {
24732544 MethodCallResolution:: methodInfoNonBlanket ( _, name , arity , abs , constraint , strippedTypePath ,
24742545 strippedType ) and
2475- not abs .( ImplItemNode ) .isBlanketImplementation ( ) and
24762546 (
24772547 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
24782548 or
@@ -2483,9 +2553,15 @@ private module OperationResolution {
24832553 pragma [ nomagic]
24842554 predicate potentialInstantiationOf ( Op op , TypeAbstraction abs , FunctionType constraint ) {
24852555 exists ( Trait trait , string name , int arity , TypePath strippedTypePath , Type strippedType |
2486- op .hasInfo ( strippedTypePath , strippedType , trait , name , arity ) and
2556+ op .hasSignature ( strippedTypePath , strippedType , trait , name , arity ) and
24872557 methodInfoNonBlanket ( abs , constraint , trait , name , arity , strippedTypePath , strippedType )
24882558 )
2559+ or
2560+ exists ( Function m |
2561+ MethodCallResolution:: methodInfoBlanket ( m , _, _, abs , _, constraint , _, _) and
2562+ MethodCallResolution:: BlanketImplementation:: SatisfiesBlanketConstraint< Op , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( op ,
2563+ m )
2564+ )
24892565 }
24902566
24912567 predicate relevantTypeMention ( FunctionType constraint ) {
0 commit comments