@@ -1238,7 +1238,8 @@ private module MethodCallResolution {
12381238 derefChain = ""
12391239 or
12401240 exists ( TypePath path0 , Type t0 , string derefChain0 |
1241- t0 = this .getACandidateReceiverTypeAtNoMatch ( path0 , derefChain0 )
1241+ this .noCandidateReceiverTypeAt ( derefChain0 ) and
1242+ t0 = this .getACandidateReceiverTypeAtNoBorrow ( path0 , derefChain0 )
12421243 |
12431244 path0 .isCons ( TRefTypeParameter ( ) , path ) and
12441245 result = t0 and
@@ -1252,23 +1253,29 @@ private module MethodCallResolution {
12521253 )
12531254 }
12541255
1256+ /**
1257+ * Holds if the method inside `i` with matching name and arity can be ruled out
1258+ * as a candidate for the receiver type represented by `derefChainBorrow`.
1259+ */
12551260 pragma [ nomagic]
12561261 private predicate isNotCandidate ( ImplOrTraitItemNode i , string derefChainBorrow ) {
12571262 IsInstantiationOf< MethodCallCand , FunctionType , MethodCallIsInstantiationOfInput > :: isNotInstantiationOf ( MkMethodCallCand ( this ,
12581263 derefChainBorrow ) , i , _)
12591264 or
1260- // not MethodCallIsInstantiationOfInput::potentialInstantiationOf(mcc, abs, constraint)
12611265 exists ( Type rootType , TypePath selfRootPath , Type selfRootType |
12621266 rootType = this .getACandidateReceiverTypeAtSubstituteTraitBounds ( derefChainBorrow ) and
1263- // mcc.isMethodCall(mc, selfPath, selfType, name, arity) and
12641267 methodCallCandidate ( this , i , _, rootType , selfRootPath , selfRootType ) and
12651268 selfRootType !=
12661269 this .getACandidateReceiverTypeAtSubstituteTraitBounds ( selfRootPath , derefChainBorrow )
12671270 )
12681271 }
12691272
1273+ /**
1274+ * Holds if the candidate receiver type represented by `derefChain` does not
1275+ * have a matching method target.
1276+ */
12701277 pragma [ nomagic]
1271- private predicate getACandidateReceiverTypeAtNoBorrowNoMatch0 ( string derefChain ) {
1278+ private predicate noCandidateReceiverTypeAtNoBorrow ( string derefChain ) {
12721279 exists ( Type rootType , string derefChainBorrow |
12731280 derefChainBorrow = derefChain + ";" and
12741281 not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
@@ -1280,43 +1287,36 @@ private module MethodCallResolution {
12801287 )
12811288 }
12821289
1283- pragma [ nomagic]
1284- private Type getACandidateReceiverTypeAtNoBorrowNoMatch ( TypePath path , string derefChain ) {
1285- result = this .getACandidateReceiverTypeAtNoBorrow ( path , derefChain ) and
1286- this .getACandidateReceiverTypeAtNoBorrowNoMatch0 ( derefChain )
1287- }
1288-
12891290 pragma [ nomagic]
12901291 private predicate hasRefCandidate ( ImplOrTraitItemNode i ) {
12911292 methodCallCandidate ( this , i , _, TRefType ( ) , _, _)
12921293 }
12931294
1295+ /**
1296+ * Holds if the candidate receiver type represented by `derefChain;borrow` does not
1297+ * have a matching method target.
1298+ */
12941299 pragma [ nomagic]
1295- private predicate getACandidateReceiverTypeAtNoMatch0 ( string derefChain ) {
1300+ private predicate noCandidateReceiverTypeAt ( string derefChain ) {
12961301 exists ( string derefChainBorrow |
12971302 derefChainBorrow = derefChain + ";borrow" and
1298- this .getACandidateReceiverTypeAtNoBorrowNoMatch0 ( derefChain )
1303+ this .noCandidateReceiverTypeAtNoBorrow ( derefChain )
12991304 |
13001305 forall ( ImplOrTraitItemNode i | this .hasRefCandidate ( i ) |
13011306 this .isNotCandidate ( i , derefChainBorrow )
13021307 )
13031308 )
13041309 }
13051310
1306- pragma [ nomagic]
1307- private Type getACandidateReceiverTypeAtNoMatch ( TypePath path , string derefChain ) {
1308- result = this .getACandidateReceiverTypeAtNoBorrowNoMatch ( path , derefChain ) and
1309- this .getACandidateReceiverTypeAtNoMatch0 ( derefChain )
1310- }
1311-
13121311 /**
13131312 * Gets a [candidate receiver type][1] of this method call at `path`.
13141313 *
13151314 * The type is obtained by repeatedly dereferencing the receiver expression's type,
13161315 * as long as the method cannot be resolved in an earlier candidate type, and possibly
13171316 * applying a borrow at the end.
13181317 *
1319- * The string `derefChainBorrow` encodes the above, separated by a semi-colon.
1318+ * The string `derefChainBorrow` encodes the sequences of dereferences and whether a
1319+ * borrow has been applied.
13201320 *
13211321 * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
13221322 */
@@ -1326,19 +1326,24 @@ private module MethodCallResolution {
13261326 result = this .getACandidateReceiverTypeAtNoBorrow ( path , derefChain ) and
13271327 derefChainBorrow = derefChain + ";"
13281328 or
1329- exists ( TypePath path0 , Type t0 |
1330- t0 = this .getACandidateReceiverTypeAtNoBorrowNoMatch ( path0 , derefChain ) and
1331- derefChainBorrow = derefChain + ";borrow"
1332- |
1329+ this .noCandidateReceiverTypeAtNoBorrow ( derefChain ) and
1330+ derefChainBorrow = derefChain + ";borrow" and
1331+ (
13331332 path .isEmpty ( ) and
13341333 result = TRefType ( )
13351334 or
1336- path = TypePath:: cons ( TRefTypeParameter ( ) , path0 ) and
1337- result = t0
1335+ exists ( TypePath suffix |
1336+ result = this .getACandidateReceiverTypeAtNoBorrow ( suffix , derefChain ) and
1337+ path = TypePath:: cons ( TRefTypeParameter ( ) , suffix )
1338+ )
13381339 )
13391340 )
13401341 }
13411342
1343+ /**
1344+ * Same as `getACandidateReceiverTypeAt`, but with traits substituted in for types
1345+ * with trait bounds.
1346+ */
13421347 pragma [ nomagic]
13431348 Type getACandidateReceiverTypeAtSubstituteTraitBounds ( TypePath path , string derefChainBorrow ) {
13441349 result = substituteTraitBounds ( this .getACandidateReceiverTypeAt ( path , derefChainBorrow ) )
@@ -1427,19 +1432,16 @@ private module MethodCallResolution {
14271432 mc .isMethodCall ( name , arity )
14281433 }
14291434
1435+ /**
1436+ * Holds if the inherent method inside `i` with matching name and arity can be
1437+ * ruled out as a candidate for this call.
1438+ */
14301439 pragma [ nomagic]
1431- private predicate isNotInherentTarget ( Impl impl ) {
1440+ private predicate isNotInherentCandidate ( Impl impl ) {
14321441 IsInstantiationOf< MethodCallCand , FunctionType , MethodCallIsNotInstantiationOfInput > :: isNotInstantiationOf ( this ,
14331442 impl , _)
14341443 }
14351444
1436- // pragma[nomagic]
1437- // private predicate blah(
1438- // Type type, Impl i, FunctionType self, TypePath selfRootPath, Type selfRootType
1439- // ) {
1440- // not i.hasTrait() and
1441- // mc_.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1442- // }
14431445 /**
14441446 * Holds if this method call has no inherent target, i.e., it does not
14451447 * resolve to a method in an `impl` block for the type of the receiver.
@@ -1452,14 +1454,7 @@ private module MethodCallResolution {
14521454 methodInfo ( _, name , arity , i , self , rootType , selfRootPath , selfRootType ) and
14531455 not i .hasTrait ( )
14541456 |
1455- // this.blah(type, i, self, selfPath, selfType)
1456- // or
1457- this .isNotInherentTarget ( i )
1458- // forall(Impl impl |
1459- // methodInfo(type, name, arity, impl, _, _, _) and
1460- // not impl.hasTrait()
1461- // |
1462- // this.isNotInherentTarget(impl)
1457+ this .isNotInherentCandidate ( i )
14631458 )
14641459 )
14651460 }
@@ -1518,6 +1513,10 @@ private module MethodCallResolution {
15181513 Location getLocation ( ) { result = mc_ .getLocation ( ) }
15191514 }
15201515
1516+ /**
1517+ * A configuration for matching the type of a receiver against the type of
1518+ * a `self` parameter.
1519+ */
15211520 private module MethodCallIsInstantiationOfInput implements
15221521 IsInstantiationOfInputSig< MethodCallCand , FunctionType >
15231522 {
@@ -1528,7 +1527,6 @@ private module MethodCallResolution {
15281527 exists ( MethodCall mc , string name , int arity , TypePath selfRootPath , Type selfRootType |
15291528 mcc .isMethodCall ( mc , selfRootPath , selfRootType , name , arity ) and
15301529 methodCallCandidate ( mc , abs , constraint , _, selfRootPath , selfRootType )
1531- // mc = Debug::getRelevantLocatable()
15321530 )
15331531 }
15341532
@@ -1537,6 +1535,10 @@ private module MethodCallResolution {
15371535 }
15381536 }
15391537
1538+ /**
1539+ * A configuration for anti-matching the type of a receiver against the type of
1540+ * a `self` parameter in an inherent method.
1541+ */
15401542 private module MethodCallIsNotInstantiationOfInput implements
15411543 IsInstantiationOfInputSig< MethodCallCand , FunctionType >
15421544 {
@@ -1548,7 +1550,6 @@ private module MethodCallResolution {
15481550 exists ( MethodCall mc , string name , int arity , Type rootType |
15491551 mcc .isMethodCall ( mc , TypePath:: nil ( ) , rootType , name , arity ) and
15501552 methodCallCandidate ( mc , abs , constraint , rootType , _, _)
1551- // mc = Debug::getRelevantLocatable()
15521553 )
15531554 }
15541555
@@ -1857,8 +1858,7 @@ private module FunctionCallResolution {
18571858 /**
18581859 * Gets the target of this call, where resolution does not rely on type inference.
18591860 */
1860- // inline to reduce non-linear recursion
1861- pragma [ inline]
1861+ pragma [ nomagic]
18621862 private ItemNode resolveUnambigousFunctionCallTarget ( ) {
18631863 (
18641864 result = this .getATraitCandidateMethod ( _, _, _, _)
@@ -1869,8 +1869,6 @@ private module FunctionCallResolution {
18691869 not functionResolutionDependsOnArgument ( _, result , _, _, _)
18701870 }
18711871
1872- // inline to reduce non-linear recursion
1873- pragma [ inline]
18741872 ItemNode resolveCallTarget ( ) {
18751873 result = this .resolveUnambigousFunctionCallTarget ( )
18761874 or
0 commit comments