@@ -1572,20 +1572,18 @@ private module MethodResolution {
15721572 }
15731573
15741574 /**
1575- * Same as `getACandidateReceiverTypeAt`, but with traits substituted in for types
1576- * with trait bounds.
1575+ * Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`.
15771576 */
15781577 pragma [ nomagic]
1579- Type getACandidateReceiverTypeAtSubstituteLookupTraits (
1580- string derefChain , boolean borrow , TypePath path
1581- ) {
1582- result = substituteLookupTraits ( this . getACandidateReceiverTypeAt ( derefChain , borrow , path ) )
1578+ Type getANonPseudoCandidateReceiverTypeAt ( string derefChain , boolean borrow , TypePath path ) {
1579+ result = this . getACandidateReceiverTypeAt ( derefChain , borrow , path ) and
1580+ result != TNeverType ( ) and
1581+ result != TUnknownType ( )
15831582 }
15841583
15851584 pragma [ nomagic]
15861585 private Type getComplexStrippedType ( string derefChain , boolean borrow , TypePath strippedTypePath ) {
1587- result =
1588- this .getACandidateReceiverTypeAtSubstituteLookupTraits ( derefChain , borrow , strippedTypePath ) and
1586+ result = this .getANonPseudoCandidateReceiverTypeAt ( derefChain , borrow , strippedTypePath ) and
15891587 isComplexRootStripped ( strippedTypePath , result )
15901588 }
15911589
@@ -1624,23 +1622,58 @@ private module MethodResolution {
16241622 )
16251623 }
16261624
1625+ // forex using recursion
1626+ pragma [ nomagic]
1627+ private predicate hasNoCompatibleTargetNoBorrowToIndex (
1628+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1629+ ) {
1630+ (
1631+ this .supportsAutoDerefAndBorrow ( )
1632+ or
1633+ // needed for the `hasNoCompatibleTarget` check in
1634+ // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1635+ derefChain = ""
1636+ ) and
1637+ strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1638+ n = - 1
1639+ or
1640+ this .hasNoCompatibleTargetNoBorrowToIndex ( derefChain , strippedTypePath , strippedType , n - 1 ) and
1641+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1642+ this .hasNoCompatibleTargetCheck ( derefChain , false , strippedTypePath , t )
1643+ )
1644+ }
1645+
16271646 /**
16281647 * Holds if the candidate receiver type represented by `derefChain` does not
16291648 * have a matching method target.
16301649 */
16311650 pragma [ nomagic]
16321651 predicate hasNoCompatibleTargetNoBorrow ( string derefChain ) {
1652+ exists ( Type strippedType |
1653+ this .hasNoCompatibleTargetNoBorrowToIndex ( derefChain , _, strippedType ,
1654+ getLastLookupTypeIndex ( strippedType ) )
1655+ )
1656+ }
1657+
1658+ // forex using recursion
1659+ pragma [ nomagic]
1660+ private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
1661+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1662+ ) {
16331663 (
16341664 this .supportsAutoDerefAndBorrow ( )
16351665 or
16361666 // needed for the `hasNoCompatibleTarget` check in
16371667 // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
16381668 derefChain = ""
16391669 ) and
1640- exists ( TypePath strippedTypePath , Type strippedType |
1641- not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
1642- strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1643- this .hasNoCompatibleTargetCheck ( derefChain , false , strippedTypePath , strippedType )
1670+ strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1671+ n = - 1
1672+ or
1673+ this .hasNoCompatibleNonBlanketTargetNoBorrowToIndex ( derefChain , strippedTypePath ,
1674+ strippedType , n - 1 ) and
1675+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1676+ this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , false , strippedTypePath , t )
16441677 )
16451678 }
16461679
@@ -1650,17 +1683,24 @@ private module MethodResolution {
16501683 */
16511684 pragma [ nomagic]
16521685 predicate hasNoCompatibleNonBlanketTargetNoBorrow ( string derefChain ) {
1653- (
1654- this .supportsAutoDerefAndBorrow ( )
1655- or
1656- // needed for the `hasNoCompatibleTarget` check in
1657- // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1658- derefChain = ""
1659- ) and
1660- exists ( TypePath strippedTypePath , Type strippedType |
1661- not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
1662- strippedType = this .getComplexStrippedType ( derefChain , false , strippedTypePath ) and
1663- this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , false , strippedTypePath , strippedType )
1686+ exists ( Type strippedType |
1687+ this .hasNoCompatibleNonBlanketTargetNoBorrowToIndex ( derefChain , _, strippedType ,
1688+ getLastLookupTypeIndex ( strippedType ) )
1689+ )
1690+ }
1691+
1692+ // forex using recursion
1693+ pragma [ nomagic]
1694+ private predicate hasNoCompatibleTargetBorrowToIndex (
1695+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1696+ ) {
1697+ this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1698+ strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1699+ n = - 1
1700+ or
1701+ this .hasNoCompatibleTargetBorrowToIndex ( derefChain , strippedTypePath , strippedType , n - 1 ) and
1702+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1703+ this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , true , strippedTypePath , t )
16641704 )
16651705 }
16661706
@@ -1670,11 +1710,25 @@ private module MethodResolution {
16701710 */
16711711 pragma [ nomagic]
16721712 predicate hasNoCompatibleTargetBorrow ( string derefChain ) {
1673- exists ( TypePath strippedTypePath , Type strippedType |
1674- this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1675- strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1676- this .hasNoCompatibleNonBlanketLikeTargetCheck ( derefChain , true , strippedTypePath ,
1677- strippedType )
1713+ exists ( Type strippedType |
1714+ this .hasNoCompatibleTargetBorrowToIndex ( derefChain , _, strippedType ,
1715+ getLastLookupTypeIndex ( strippedType ) )
1716+ )
1717+ }
1718+
1719+ // forex using recursion
1720+ pragma [ nomagic]
1721+ private predicate hasNoCompatibleNonBlanketTargetBorrowToIndex (
1722+ string derefChain , TypePath strippedTypePath , Type strippedType , int n
1723+ ) {
1724+ this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1725+ strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1726+ n = - 1
1727+ or
1728+ this .hasNoCompatibleNonBlanketTargetBorrowToIndex ( derefChain , strippedTypePath , strippedType ,
1729+ n - 1 ) and
1730+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1731+ this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , true , strippedTypePath , t )
16781732 )
16791733 }
16801734
@@ -1684,10 +1738,9 @@ private module MethodResolution {
16841738 */
16851739 pragma [ nomagic]
16861740 predicate hasNoCompatibleNonBlanketTargetBorrow ( string derefChain ) {
1687- exists ( TypePath strippedTypePath , Type strippedType |
1688- this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
1689- strippedType = this .getComplexStrippedType ( derefChain , true , strippedTypePath ) and
1690- this .hasNoCompatibleNonBlanketTargetCheck ( derefChain , true , strippedTypePath , strippedType )
1741+ exists ( Type strippedType |
1742+ this .hasNoCompatibleNonBlanketTargetBorrowToIndex ( derefChain , _, strippedType ,
1743+ getLastLookupTypeIndex ( strippedType ) )
16911744 )
16921745 }
16931746
@@ -1905,9 +1958,8 @@ private module MethodResolution {
19051958 MethodCall getMethodCall ( ) { result = mc_ }
19061959
19071960 Type getTypeAt ( TypePath path ) {
1908- result = mc_ .getACandidateReceiverTypeAtSubstituteLookupTraits ( derefChain , borrow , path ) and
1909- not result = TNeverType ( ) and
1910- not result = TUnknownType ( )
1961+ result =
1962+ substituteLookupTraits ( mc_ .getANonPseudoCandidateReceiverTypeAt ( derefChain , borrow , path ) )
19111963 }
19121964
19131965 pragma [ nomagic]
0 commit comments