@@ -1471,20 +1471,18 @@ private module MethodResolution {
14711471 }
14721472
14731473 /**
1474- * Same as `getACandidateReceiverTypeAt`, but with traits substituted in for types
1475- * with trait bounds.
1474+ * Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`.
14761475 */
14771476 pragma [ nomagic]
1478- Type getACandidateReceiverTypeAtSubstituteLookupTraits (
1479- string derefChain , boolean borrow , TypePath path
1480- ) {
1481- result = substituteLookupTraits ( this . getACandidateReceiverTypeAt ( derefChain , borrow , path ) )
1477+ Type getANonPseudoCandidateReceiverTypeAt ( string derefChain , boolean borrow , TypePath path ) {
1478+ result = this . getACandidateReceiverTypeAt ( derefChain , borrow , path ) and
1479+ result != TNeverType ( ) and
1480+ result != TUnknownType ( )
14821481 }
14831482
14841483 pragma [ nomagic]
14851484 private Type getComplexStrippedType ( string derefChain , boolean borrow , TypePath strippedTypePath ) {
1486- result =
1487- this .getACandidateReceiverTypeAtSubstituteLookupTraits ( derefChain , borrow , strippedTypePath ) and
1485+ result = this .getANonPseudoCandidateReceiverTypeAt ( derefChain , borrow , strippedTypePath ) and
14881486 isComplexRootStripped ( strippedTypePath , result )
14891487 }
14901488
@@ -1523,23 +1521,58 @@ private module MethodResolution {
15231521 )
15241522 }
15251523
1524+ // forex using recursion
1525+ pragma [ nomagic]
1526+ private predicate hasNoCompatibleTargetNoBorrowToIndex (
1527+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1528+ ) {
1529+ (
1530+ this .supportsAutoDerefAndBorrow ( )
1531+ or
1532+ // needed for the `hasNoCompatibleTarget` check in
1533+ // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1534+ derefChain = ""
1535+ ) and
1536+ strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1537+ n = - 1
1538+ or
1539+ this .hasNoCompatibleTargetNoBorrowToIndex ( derefChain , strippedTypePath , strippedType , n - 1 ) and
1540+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1541+ this .hasNoCompatibleTargetCheck ( derefChain , false , strippedTypePath , t )
1542+ )
1543+ }
1544+
15261545 /**
15271546 * Holds if the candidate receiver type represented by `derefChain` does not
15281547 * have a matching method target.
15291548 */
15301549 pragma [ nomagic]
15311550 predicate hasNoCompatibleTargetNoBorrow ( string derefChain ) {
1551+ exists ( Type strippedType |
1552+ this .hasNoCompatibleTargetNoBorrowToIndex ( derefChain , _, strippedType ,
1553+ getLastLookupTypeIndex ( strippedType ) )
1554+ )
1555+ }
1556+
1557+ // forex using recursion
1558+ pragma [ nomagic]
1559+ private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
1560+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1561+ ) {
15321562 (
15331563 this .supportsAutoDerefAndBorrow ( )
15341564 or
15351565 // needed for the `hasNoCompatibleTarget` check in
15361566 // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
15371567 derefChain = ""
15381568 ) and
1539- exists ( TypePath strippedTypePath , Type strippedType |
1540- not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
1541- strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1542- this .hasNoCompatibleTargetCheck ( derefChain , false , strippedTypePath , strippedType )
1569+ strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1570+ n = - 1
1571+ or
1572+ this .hasNoCompatibleNonBlanketTargetNoBorrowToIndex ( derefChain , strippedTypePath ,
1573+ strippedType , n - 1 ) and
1574+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1575+ this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , false , strippedTypePath , t )
15431576 )
15441577 }
15451578
@@ -1549,17 +1582,24 @@ private module MethodResolution {
15491582 */
15501583 pragma [ nomagic]
15511584 predicate hasNoCompatibleNonBlanketTargetNoBorrow ( string derefChain ) {
1552- (
1553- this .supportsAutoDerefAndBorrow ( )
1554- or
1555- // needed for the `hasNoCompatibleTarget` check in
1556- // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1557- derefChain = ""
1558- ) and
1559- exists ( TypePath strippedTypePath , Type strippedType |
1560- not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
1561- strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1562- this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , false , strippedTypePath , strippedType )
1585+ exists ( Type strippedType |
1586+ this .hasNoCompatibleNonBlanketTargetNoBorrowToIndex ( derefChain , _, strippedType ,
1587+ getLastLookupTypeIndex ( strippedType ) )
1588+ )
1589+ }
1590+
1591+ // forex using recursion
1592+ pragma [ nomagic]
1593+ private predicate hasNoCompatibleTargetBorrowToIndex (
1594+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1595+ ) {
1596+ this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1597+ strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1598+ n = - 1
1599+ or
1600+ this .hasNoCompatibleTargetBorrowToIndex ( derefChain , strippedTypePath , strippedType , n - 1 ) and
1601+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1602+ this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , true , strippedTypePath , t )
15631603 )
15641604 }
15651605
@@ -1569,11 +1609,25 @@ private module MethodResolution {
15691609 */
15701610 pragma [ nomagic]
15711611 predicate hasNoCompatibleTargetBorrow ( string derefChain ) {
1572- exists ( TypePath strippedTypePath , Type strippedType |
1573- this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1574- strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1575- this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , true , strippedTypePath ,
1576- strippedType )
1612+ exists ( Type strippedType |
1613+ this .hasNoCompatibleTargetBorrowToIndex ( derefChain , _, strippedType ,
1614+ getLastLookupTypeIndex ( strippedType ) )
1615+ )
1616+ }
1617+
1618+ // forex using recursion
1619+ pragma [ nomagic]
1620+ private predicate hasNoCompatibleNonBlanketTargetBorrowToIndex (
1621+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1622+ ) {
1623+ this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1624+ strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1625+ n = - 1
1626+ or
1627+ this .hasNoCompatibleNonBlanketTargetBorrowToIndex ( derefChain , strippedTypePath , strippedType ,
1628+ n - 1 ) and
1629+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1630+ this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , true , strippedTypePath , t )
15771631 )
15781632 }
15791633
@@ -1583,10 +1637,9 @@ private module MethodResolution {
15831637 */
15841638 pragma [ nomagic]
15851639 predicate hasNoCompatibleNonBlanketTargetBorrow ( string derefChain ) {
1586- exists ( TypePath strippedTypePath , Type strippedType |
1587- this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1588- strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1589- this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , true , strippedTypePath , strippedType )
1640+ exists ( Type strippedType |
1641+ this .hasNoCompatibleNonBlanketTargetBorrowToIndex ( derefChain , _, strippedType ,
1642+ getLastLookupTypeIndex ( strippedType ) )
15901643 )
15911644 }
15921645
@@ -1804,9 +1857,8 @@ private module MethodResolution {
18041857 MethodCall getMethodCall ( ) { result = mc_ }
18051858
18061859 Type getTypeAt ( TypePath path ) {
1807- result = mc_ .getACandidateReceiverTypeAtSubstituteLookupTraits ( derefChain , borrow , path ) and
1808- not result = TNeverType ( ) and
1809- not result = TUnknownType ( )
1860+ result =
1861+ substituteLookupTraits ( mc_ .getANonPseudoCandidateReceiverTypeAt ( derefChain , borrow , path ) )
18101862 }
18111863
18121864 pragma [ nomagic]
0 commit comments