@@ -1025,6 +1025,7 @@ private class FunctionPositionType extends TFunctionPositionType {
10251025 this .asInheritedFunctionPositionType ( f , pos , _, i )
10261026 }
10271027
1028+ pragma [ nomagic]
10281029 private Type getTypeAt0 ( TypePath path ) {
10291030 exists ( Function f , FunctionPosition pos | this .asFunctionPositionType ( f , pos , _) |
10301031 pos .asArgumentPosition ( ) .isSelf ( ) and
@@ -1047,13 +1048,18 @@ private class FunctionPositionType extends TFunctionPositionType {
10471048 not result instanceof TSelfTypeParameter
10481049 or
10491050 exists ( TypePath prefix , TypePath suffix |
1050- parentType .getTypeAt0 ( prefix ) = TSelfTypeParameter ( _ ) and
1051+ parentType .hasSelfTypeParameterAt ( prefix ) and
10511052 result = resolveImplOrTraitType ( i , suffix ) and
10521053 path = prefix .append ( suffix )
10531054 )
10541055 )
10551056 }
10561057
1058+ pragma [ nomagic]
1059+ private predicate hasSelfTypeParameterAt ( TypePath path ) {
1060+ this .getTypeAt0 ( path ) = TSelfTypeParameter ( _)
1061+ }
1062+
10571063 Type getTypeAt ( TypePath path ) {
10581064 // For methods belonging to a `trait`, we use the type of the trait itself
10591065 // instead of the implicit `Self` type parameter, as otherwise any type will
@@ -1113,6 +1119,50 @@ private module MethodCallResolution {
11131119 )
11141120 }
11151121
1122+ pragma [ nomagic]
1123+ private predicate methodCandidateImplTrait ( string name , int arity , Trait trait ) {
1124+ exists ( ImplItemNode i |
1125+ methodCandidate ( _, name , arity , i , _) and
1126+ trait = i .resolveTraitTy ( )
1127+ )
1128+ }
1129+
1130+ pragma [ nomagic]
1131+ private predicate methodCallTraitCandidate ( Element mc , Trait trait ) {
1132+ exists ( string name , int arity |
1133+ mc .( MethodCall ) .isMethodCall ( name , arity ) and
1134+ methodCandidateImplTrait ( name , arity , trait )
1135+ )
1136+ }
1137+
1138+ private predicate methodCallVisibleTraitCandidate ( MethodCall mc , Trait trait ) {
1139+ TraitIsVisible< methodCallTraitCandidate / 2 > :: traitIsVisible ( mc , trait )
1140+ }
1141+
1142+ bindingset [ mc, impl]
1143+ pragma [ inline_late]
1144+ private predicate methodCallVisibleImplTraitCandidate ( MethodCall mc , ImplItemNode impl ) {
1145+ methodCallVisibleTraitCandidate ( mc , impl .resolveTraitTy ( ) )
1146+ }
1147+
1148+ pragma [ nomagic]
1149+ private predicate methodCallCandidate (
1150+ MethodCall mc , Type type , ImplOrTraitItemNode i , FunctionPositionType self
1151+ ) {
1152+ exists ( string name , int arity |
1153+ mc .isMethodCall ( name , arity ) and
1154+ methodCandidate ( type , name , arity , i , self ) //and
1155+ |
1156+ // not CertainTypeInference::inferCertainType(mc.getReceiver(), TypePath::nil()) != type
1157+ not exists ( i .( ImplItemNode ) .resolveTraitTy ( ) )
1158+ or
1159+ methodCallVisibleImplTraitCandidate ( mc , i )
1160+ or
1161+ mc instanceof IndexExpr and
1162+ i .( ImplItemNode ) .resolveTraitTy ( ) instanceof IndexTrait
1163+ )
1164+ }
1165+
11161166 /**
11171167 * A method call.
11181168 *
@@ -1139,9 +1189,9 @@ private module MethodCallResolution {
11391189
11401190 abstract Expr getArgument ( ArgumentPosition pos ) ;
11411191
1142- private Type getReceiverTypeAt ( TypePath path ) {
1143- result = inferType ( this . getArgument ( any ( ArgumentPosition pos | pos . isSelf ( ) ) ) , path )
1144- }
1192+ Expr getReceiver ( ) { result = this . getArgument ( any ( ArgumentPosition pos | pos . isSelf ( ) ) ) }
1193+
1194+ private Type getReceiverTypeAt ( TypePath path ) { result = inferType ( this . getReceiver ( ) , path ) }
11451195
11461196 /**
11471197 * Same as `getACandidateReceiverTypeAt`, but without borrows.
@@ -1167,48 +1217,29 @@ private module MethodCallResolution {
11671217 }
11681218
11691219 pragma [ nomagic]
1170- private predicate isMethodCall0 ( Type rootType , string name , int arity , string derefChainBorrow ) {
1171- rootType = this .getACandidateReceiverTypeAt ( TypePath:: nil ( ) , derefChainBorrow ) and
1220+ private predicate isMethodCall0 ( Type type , string name , int arity , string derefChainBorrow ) {
1221+ type = this .getACandidateReceiverTypeAt ( TypePath:: nil ( ) , derefChainBorrow ) and
11721222 this .isMethodCall ( name , arity )
11731223 }
11741224
1175- pragma [ nomagic]
1176- predicate hasTraitImplCandidate (
1177- ImplItemNode i , FunctionPositionType self , string derefChainBorrow , Trait trait
1178- ) {
1179- exists ( Type rootType , string name , int arity |
1180- this .isMethodCall0 ( rootType , name , arity , derefChainBorrow ) and
1181- methodCandidate ( rootType , name , arity , i , self ) and
1182- trait = i .resolveTraitTy ( )
1183- )
1184- }
1185-
11861225 pragma [ nomagic]
11871226 private predicate isNotCandidate (
11881227 ImplOrTraitItemNode i , FunctionPositionType self , string derefChainBorrow
11891228 ) {
11901229 IsInstantiationOf< MethodCallCand , FunctionPositionType , MethodCallIsInstantiationOfInput > :: isNotInstantiationOf ( MkMethodCallCand ( this ,
11911230 derefChainBorrow ) , i , self )
1192- or
1193- exists ( Trait trait |
1194- this .hasTraitImplCandidate ( i , self , derefChainBorrow , trait ) and
1195- TraitIsVisible< relevantTraitVisible1 / 2 > :: traitIsNotVisible ( this , trait )
1196- |
1197- not this instanceof IndexExpr or
1198- not trait instanceof IndexTrait
1199- )
12001231 }
12011232
12021233 pragma [ nomagic]
12031234 private Type getACandidateReceiverTypeAtNoBorrowNoMatch ( TypePath path , string derefChain ) {
12041235 result = this .getACandidateReceiverTypeAtNoBorrow ( path , derefChain ) and
1205- exists ( Type rootType , string name , int arity , string derefChainBorrow |
1236+ exists ( Type type , string name , int arity , string derefChainBorrow |
12061237 derefChainBorrow = derefChain + ";" and
12071238 not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
1208- this .isMethodCall0 ( rootType , name , arity , derefChainBorrow )
1239+ this .isMethodCall0 ( type , name , arity , derefChainBorrow )
12091240 |
12101241 forall ( ImplOrTraitItemNode i , FunctionPositionType self |
1211- methodCandidate ( rootType , name , arity , i , self )
1242+ methodCallCandidate ( this , type , i , self )
12121243 |
12131244 this .isNotCandidate ( i , self , derefChainBorrow )
12141245 )
@@ -1218,12 +1249,12 @@ private module MethodCallResolution {
12181249 pragma [ nomagic]
12191250 private Type getACandidateReceiverTypeAtNoMatch ( TypePath path , string derefChain ) {
12201251 result = this .getACandidateReceiverTypeAtNoBorrowNoMatch ( path , derefChain ) and
1221- exists ( Type rootType , string name , int arity , string derefChainBorrow |
1252+ exists ( Type type , string name , int arity , string derefChainBorrow |
12221253 derefChainBorrow = derefChain + ";borrow" and
1223- this .isMethodCall0 ( rootType , name , arity , derefChainBorrow )
1254+ this .isMethodCall0 ( type , name , arity , derefChainBorrow )
12241255 |
12251256 forall ( ImplOrTraitItemNode i , FunctionPositionType self |
1226- methodCandidate ( rootType , name , arity , i , self )
1257+ methodCallCandidate ( this , type , i , self )
12271258 |
12281259 this .isNotCandidate ( i , self , derefChainBorrow )
12291260 )
@@ -1281,22 +1312,18 @@ private module MethodCallResolution {
12811312 }
12821313 }
12831314
1284- private predicate relevantTraitVisible1 ( Element mc , Trait trait ) {
1285- mc .( MethodCall ) .hasTraitImplCandidate ( _, _, _, trait )
1286- }
1287-
1288- private class MethodCallMethodCallExpr extends MethodCall , MethodCallExpr {
1315+ private class MethodCallMethodCallExpr extends MethodCall instanceof MethodCallExpr {
12891316 pragma [ nomagic]
12901317 override predicate isMethodCall ( string name , int arity ) {
1291- name = this .getIdentifier ( ) .getText ( ) and
1292- arity = this .getArgList ( ) .getNumberOfArgs ( )
1318+ name = super .getIdentifier ( ) .getText ( ) and
1319+ arity = super .getArgList ( ) .getNumberOfArgs ( )
12931320 }
12941321
12951322 override Expr getArgument ( ArgumentPosition pos ) {
12961323 pos .isSelf ( ) and
1297- result = this .getReceiver ( )
1324+ result = MethodCallExpr . super .getReceiver ( )
12981325 or
1299- result = this .getArgList ( ) .getArg ( pos .asPosition ( ) )
1326+ result = super .getArgList ( ) .getArg ( pos .asPosition ( ) )
13001327 }
13011328 }
13021329
@@ -1323,15 +1350,15 @@ private module MethodCallResolution {
13231350
13241351 /** A method call tagged with a candidate receiver type. */
13251352 private class MethodCallCand extends MkMethodCallCand {
1326- MethodCall mc ;
1353+ MethodCall mc_ ;
13271354 string derefChainBorrow ;
13281355
1329- MethodCallCand ( ) { this = MkMethodCallCand ( mc , derefChainBorrow ) }
1356+ MethodCallCand ( ) { this = MkMethodCallCand ( mc_ , derefChainBorrow ) }
13301357
1331- MethodCall getMethodCall ( ) { result = mc }
1358+ MethodCall getMethodCall ( ) { result = mc_ }
13321359
13331360 Type getTypeAt ( TypePath path ) {
1334- exists ( Type t | t = mc .getACandidateReceiverTypeAt ( path , derefChainBorrow ) |
1361+ exists ( Type t | t = mc_ .getACandidateReceiverTypeAt ( path , derefChainBorrow ) |
13351362 not exists ( getATraitBound ( t ) ) and
13361363 result = t
13371364 or
@@ -1340,8 +1367,9 @@ private module MethodCallResolution {
13401367 }
13411368
13421369 pragma [ nomagic]
1343- predicate isMethodCall ( Type rootType , string name , int arity ) {
1344- rootType = this .getTypeAt ( TypePath:: nil ( ) ) and
1370+ predicate isMethodCall ( MethodCall mc , Type type , string name , int arity ) {
1371+ type = this .getTypeAt ( TypePath:: nil ( ) ) and
1372+ mc = mc_ and
13451373 mc .isMethodCall ( name , arity )
13461374 }
13471375
@@ -1358,10 +1386,10 @@ private module MethodCallResolution {
13581386 */
13591387 pragma [ nomagic]
13601388 private predicate hasNoInherentTarget ( ) {
1361- exists ( Type rootType , string name , int arity |
1362- this .isMethodCall ( rootType , name , arity ) and
1389+ exists ( Type type , string name , int arity |
1390+ this .isMethodCall ( _ , type , name , arity ) and
13631391 forall ( Impl impl |
1364- methodCandidate ( rootType , name , arity , impl , _) and
1392+ methodCandidate ( type , name , arity , impl , _) and
13651393 not impl .hasTrait ( )
13661394 |
13671395 this .isNotInherentTarget ( impl )
@@ -1373,7 +1401,7 @@ private module MethodCallResolution {
13731401 private Function resolveCallTargetCand ( ImplOrTraitItemNode i , string name ) {
13741402 IsInstantiationOf< MethodCallCand , FunctionPositionType , MethodCallIsInstantiationOfInput > :: isInstantiationOf ( this ,
13751403 i , _) and
1376- mc .isMethodCall ( name , _) and
1404+ mc_ .isMethodCall ( name , _) and
13771405 result = getMethodSuccessor ( i , name , _) and
13781406 if i .( Impl ) .hasTrait ( )
13791407 then
@@ -1394,54 +1422,31 @@ private module MethodCallResolution {
13941422 FunctionOverloading:: functionResolutionDependsOnArgument ( i , name , result , pos ,
13951423 pragma [ only_bind_into ] ( path ) , type ) and
13961424 pos .isPositional ( ) and
1397- inferType ( mc .getArgument ( pos .asArgumentPosition ( ) ) , pragma [ only_bind_into ] ( path ) ) = type
1425+ inferType ( mc_ .getArgument ( pos .asArgumentPosition ( ) ) , pragma [ only_bind_into ] ( path ) ) = type
13981426 )
13991427 )
14001428 }
14011429
1402- string toString ( ) { result = mc .toString ( ) + " [" + derefChainBorrow + "]" }
1430+ string toString ( ) { result = mc_ .toString ( ) + " [" + derefChainBorrow + "]" }
14031431
1404- Location getLocation ( ) { result = mc .getLocation ( ) }
1432+ Location getLocation ( ) { result = mc_ .getLocation ( ) }
14051433 }
14061434
14071435 private module MethodCallIsInstantiationOfInput implements
14081436 IsInstantiationOfInputSig< MethodCallCand , FunctionPositionType >
14091437 {
1410- pragma [ nomagic]
1411- private predicate methodCallCandidate (
1412- MethodCallCand mcc , MethodCall mc , ImplOrTraitItemNode i , FunctionPositionType constraint
1413- ) {
1414- exists ( Type rootType , string name , int arity |
1415- mcc .isMethodCall ( rootType , name , arity ) and
1416- methodCandidate ( rootType , name , arity , i , constraint ) and
1417- mc = mcc .getMethodCall ( )
1418- )
1419- }
1420-
1421- private predicate relevantTraitVisible ( Element mc , Trait trait ) {
1422- trait = any ( ImplItemNode impl | methodCallCandidate ( _, mc , impl , _) ) .resolveTraitTy ( )
1423- }
1424-
14251438 pragma [ nomagic]
14261439 predicate potentialInstantiationOf (
14271440 MethodCallCand mcc , TypeAbstraction abs , FunctionPositionType constraint
14281441 ) {
1429- exists ( MethodCall mc | methodCallCandidate ( mcc , mc , abs , constraint ) |
1430- not exists ( abs .( ImplItemNode ) .resolveTraitTy ( ) )
1431- or
1432- // If the `impl` block implements a trait, that trait must be visible in
1433- // order for the `impl` to be valid.
1434- exists ( Trait trait | pragma [ only_bind_into ] ( trait ) = abs .( ImplItemNode ) .resolveTraitTy ( ) |
1435- TraitIsVisible< relevantTraitVisible / 2 > :: traitIsVisible ( mc , pragma [ only_bind_into ] ( trait ) )
1436- or
1437- mc instanceof IndexExpr and
1438- trait instanceof IndexTrait
1439- )
1442+ exists ( MethodCall mc , Type type , string name , int arity |
1443+ mcc .isMethodCall ( mc , type , name , arity ) and
1444+ methodCallCandidate ( mc , type , abs , constraint )
14401445 )
14411446 }
14421447
14431448 predicate relevantTypeMention ( FunctionPositionType constraint ) {
1444- methodCandidate ( _ , _, _, _, constraint )
1449+ methodCallCandidate ( _, _, _, constraint )
14451450 }
14461451 }
14471452}
@@ -2033,10 +2038,10 @@ private module OperationResolution {
20332038 }
20342039
20352040 pragma [ nomagic]
2036- predicate isOperation ( Type rootType , Trait trait , string name , int arity ) {
2041+ predicate isOperation ( Type type , Trait trait , string name , int arity ) {
20372042 name = this .( Call ) .getMethodName ( ) and
20382043 arity = this .( Call ) .getNumberOfArguments ( ) and
2039- rootType = this .getTypeAt ( TypePath:: nil ( ) ) and
2044+ type = this .getTypeAt ( TypePath:: nil ( ) ) and
20402045 trait = this .( Call ) .getTrait ( )
20412046 }
20422047
@@ -2089,9 +2094,9 @@ private module OperationResolution {
20892094
20902095 pragma [ nomagic]
20912096 predicate potentialInstantiationOf ( Op op , TypeAbstraction abs , FunctionPositionType constraint ) {
2092- exists ( Type rootType , Trait trait , string name , int arity |
2093- op .isOperation ( rootType , trait , name , arity ) and
2094- MethodCallResolution:: methodCandidate ( rootType , name , arity , abs , constraint )
2097+ exists ( Type type , Trait trait , string name , int arity |
2098+ op .isOperation ( type , trait , name , arity ) and
2099+ MethodCallResolution:: methodCandidate ( type , name , arity , abs , constraint )
20952100 |
20962101 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
20972102 or
0 commit comments