@@ -1162,8 +1162,7 @@ private module MethodCallResolution {
11621162 mc .isMethodCall ( name , arity ) and
11631163 methodCandidate ( type , name , arity , i , self , selfPath , selfType )
11641164 |
1165- // not CertainTypeInference::inferCertainType(mc.getReceiver(), TypePath::nil()) != type
1166- not exists ( i .( ImplItemNode ) .resolveTraitTy ( ) )
1165+ not i .( Impl ) .hasTrait ( )
11671166 or
11681167 methodCallVisibleImplTraitCandidate ( mc , i )
11691168 or
@@ -1172,6 +1171,18 @@ private module MethodCallResolution {
11721171 )
11731172 }
11741173
1174+ private class RawImplOrTrait = @impl or @trait;
1175+
1176+ private import codeql.rust.elements.internal.generated.Synth
1177+
1178+ private predicate id ( RawImplOrTrait x , RawImplOrTrait y ) { x = y }
1179+
1180+ private predicate idOfRaw ( RawImplOrTrait x , int y ) = equivalenceRelation( id / 2 ) ( x , y )
1181+
1182+ private int idOfImplOrTraitItemNode ( AstNode node ) {
1183+ idOfRaw ( Synth:: convertAstNodeToRaw ( node ) , result )
1184+ }
1185+
11751186 /**
11761187 * A method call.
11771188 *
@@ -1235,22 +1246,38 @@ private module MethodCallResolution {
12351246 private predicate isNotCandidate (
12361247 ImplOrTraitItemNode i , FunctionPositionType self , string derefChainBorrow
12371248 ) {
1238- IsInstantiationOf< MethodCallCand , FunctionPositionType , MethodCallIsInstantiationOfInput > :: isNotInstantiationOf ( MkMethodCallCand ( this ,
1249+ IsInstantiationOf< MethodCallCand , FunctionPositionType , MethodCallIsInstantiationOfInput2 > :: isNotInstantiationOf ( MkMethodCallCand ( this ,
12391250 derefChainBorrow ) , i , self )
12401251 }
12411252
1253+ // pragma[nomagic]
1254+ // predicate blah(
1255+ // Type type, ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType,
1256+ // string derefChainBorrow
1257+ // ) {
1258+ // selfType != this.getACandidateReceiverTypeAt(selfPath, derefChainBorrow) and
1259+ // methodCallCandidate(this, type, i, self, selfPath, selfType)
1260+ // }
1261+ // idOfImplOrTraitItemNode
1262+ // pragma[nomagic]
1263+ // private ImplOrTraitItemNode getARankedCandidate(TypePath path, string derefChain) {
1264+ // result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
1265+ // exists(Type type, string name, int arity, string derefChainBorrow |
1266+ // derefChainBorrow = derefChain + ";" and
1267+ // not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
1268+ // this.isMethodCall0(type, name, arity, derefChainBorrow)
1269+ // |
1270+ // forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1271+ // methodCallCandidate(this, type, i, self, selfPath, selfType)
1272+ // |
1273+ // this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1274+ // or
1275+ // this.isNotCandidate(i, self, derefChainBorrow)
1276+ // )
1277+ // )
1278+ // }
12421279 pragma [ nomagic]
1243- predicate blah (
1244- Type type , ImplOrTraitItemNode i , FunctionPositionType self , TypePath selfPath , Type selfType ,
1245- string derefChainBorrow
1246- ) {
1247- selfType != this .getACandidateReceiverTypeAt ( selfPath , derefChainBorrow ) and
1248- methodCallCandidate ( this , type , i , self , selfPath , selfType )
1249- }
1250-
1251- pragma [ nomagic]
1252- private Type getACandidateReceiverTypeAtNoBorrowNoMatch ( TypePath path , string derefChain ) {
1253- result = this .getACandidateReceiverTypeAtNoBorrow ( path , derefChain ) and
1280+ private predicate getACandidateReceiverTypeAtNoBorrowNoMatch0 ( string derefChain ) {
12541281 exists ( Type type , string name , int arity , string derefChainBorrow |
12551282 derefChainBorrow = derefChain + ";" and
12561283 not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
@@ -1259,30 +1286,66 @@ private module MethodCallResolution {
12591286 forall ( ImplOrTraitItemNode i , FunctionPositionType self , TypePath selfPath , Type selfType |
12601287 methodCallCandidate ( this , type , i , self , selfPath , selfType )
12611288 |
1262- this .blah ( type , i , self , selfPath , selfType , derefChainBorrow )
1263- or
1289+ // this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1290+ // or
12641291 this .isNotCandidate ( i , self , derefChainBorrow )
12651292 )
12661293 )
12671294 }
12681295
12691296 pragma [ nomagic]
1270- private Type getACandidateReceiverTypeAtNoMatch ( TypePath path , string derefChain ) {
1271- result = this .getACandidateReceiverTypeAtNoBorrowNoMatch ( path , derefChain ) and
1297+ private Type getACandidateReceiverTypeAtNoBorrowNoMatch ( TypePath path , string derefChain ) {
1298+ result = this .getACandidateReceiverTypeAtNoBorrow ( path , derefChain ) and
1299+ this .getACandidateReceiverTypeAtNoBorrowNoMatch0 ( derefChain )
1300+ // exists(Type type, string name, int arity, string derefChainBorrow |
1301+ // derefChainBorrow = derefChain + ";" and
1302+ // not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
1303+ // this.isMethodCall0(type, name, arity, derefChainBorrow)
1304+ // |
1305+ // forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1306+ // methodCallCandidate(this, type, i, self, selfPath, selfType)
1307+ // |
1308+ // this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1309+ // or
1310+ // this.isNotCandidate(i, self, derefChainBorrow)
1311+ // )
1312+ // )
1313+ }
1314+
1315+ pragma [ nomagic]
1316+ private predicate getACandidateReceiverTypeAtNoMatch0 ( string derefChain ) {
12721317 exists ( Type type , string name , int arity , string derefChainBorrow |
12731318 derefChainBorrow = derefChain + ";borrow" and
12741319 this .isMethodCall0 ( type , name , arity , derefChainBorrow )
12751320 |
12761321 forall ( ImplOrTraitItemNode i , FunctionPositionType self , TypePath selfPath , Type selfType |
12771322 methodCallCandidate ( this , type , i , self , selfPath , selfType )
12781323 |
1279- this .blah ( type , i , self , selfPath , selfType , derefChainBorrow )
1280- or
1324+ // this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1325+ // or
12811326 this .isNotCandidate ( i , self , derefChainBorrow )
12821327 )
12831328 )
12841329 }
12851330
1331+ pragma [ nomagic]
1332+ private Type getACandidateReceiverTypeAtNoMatch ( TypePath path , string derefChain ) {
1333+ result = this .getACandidateReceiverTypeAtNoBorrowNoMatch ( path , derefChain ) and
1334+ this .getACandidateReceiverTypeAtNoMatch0 ( derefChain )
1335+ // exists(Type type, string name, int arity, string derefChainBorrow |
1336+ // derefChainBorrow = derefChain + ";borrow" and
1337+ // this.isMethodCall0(type, name, arity, derefChainBorrow)
1338+ // |
1339+ // forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1340+ // methodCallCandidate(this, type, i, self, selfPath, selfType)
1341+ // |
1342+ // this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1343+ // or
1344+ // this.isNotCandidate(i, self, derefChainBorrow)
1345+ // )
1346+ // )
1347+ }
1348+
12861349 /**
12871350 * Gets a [candidate receiver type][1] of this method call at `path`.
12881351 *
@@ -1401,14 +1464,13 @@ private module MethodCallResolution {
14011464 impl , _)
14021465 }
14031466
1404- pragma [ nomagic]
1405- private predicate blah (
1406- Type type , Impl i , FunctionPositionType self , TypePath selfPath , Type selfType
1407- ) {
1408- not i .hasTrait ( ) and
1409- mc_ .blah ( type , i , self , selfPath , selfType , derefChainBorrow )
1410- }
1411-
1467+ // pragma[nomagic]
1468+ // private predicate blah(
1469+ // Type type, Impl i, FunctionPositionType self, TypePath selfPath, Type selfType
1470+ // ) {
1471+ // not i.hasTrait() and
1472+ // mc_.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1473+ // }
14121474 /**
14131475 * Holds if this method call has no inherent target, i.e., it does not
14141476 * resolve to a method in an `impl` block for the type of the receiver.
@@ -1421,8 +1483,8 @@ private module MethodCallResolution {
14211483 methodCandidate ( type , name , arity , i , self , selfPath , selfType ) and
14221484 not i .hasTrait ( )
14231485 |
1424- this .blah ( type , i , self , selfPath , selfType )
1425- or
1486+ // this.blah(type, i, self, selfPath, selfType)
1487+ // or
14261488 this .isNotInherentTarget ( i )
14271489 // forall(Impl impl |
14281490 // methodCandidate(type, name, arity, impl, _, _, _) and
@@ -1502,14 +1564,33 @@ private module MethodCallResolution {
15021564 }
15031565 }
15041566
1567+ private module MethodCallIsInstantiationOfInput2 implements
1568+ IsInstantiationOfInputSig< MethodCallCand , FunctionPositionType >
1569+ {
1570+ pragma [ nomagic]
1571+ predicate potentialInstantiationOf (
1572+ MethodCallCand mcc , TypeAbstraction abs , FunctionPositionType constraint
1573+ ) {
1574+ exists ( MethodCall mc , string name , int arity , Type rootType |
1575+ mcc .isMethodCall ( mc , TypePath:: nil ( ) , rootType , name , arity ) and
1576+ methodCallCandidate ( mc , rootType , abs , constraint , _, _)
1577+ // mc = Debug::getRelevantLocatable()
1578+ )
1579+ }
1580+
1581+ predicate relevantTypeMention ( FunctionPositionType constraint ) {
1582+ methodCallCandidate ( _, _, _, constraint , _, _)
1583+ }
1584+ }
1585+
15051586 private module MethodCallIsNotInstantiationOfInput implements
15061587 IsInstantiationOfInputSig< MethodCallCand , FunctionPositionType >
15071588 {
15081589 pragma [ nomagic]
15091590 predicate potentialInstantiationOf (
15101591 MethodCallCand mcc , TypeAbstraction abs , FunctionPositionType constraint
15111592 ) {
1512- MethodCallIsInstantiationOfInput :: potentialInstantiationOf ( mcc , abs , constraint ) and
1593+ MethodCallIsInstantiationOfInput2 :: potentialInstantiationOf ( mcc , abs , constraint ) and
15131594 abs = any ( Impl i | not i .hasTrait ( ) )
15141595 }
15151596
0 commit comments