@@ -1353,7 +1353,7 @@ private class BorrowKind extends TBorrowKind {
13531353private module AssocFunctionResolution {
13541354 /**
13551355 * Holds if function `f` with the name `name` and the arity `arity` exists in
1356- * `i`, and the type at position `posAdj` is `t`.
1356+ * `i`, and the type at adjusted position `posAdj` is `t`.
13571357 */
13581358 pragma [ nomagic]
13591359 private predicate assocFunctionInfo (
@@ -1370,29 +1370,29 @@ private module AssocFunctionResolution {
13701370
13711371 /**
13721372 * Holds if function `f` with the name `name` and the arity `arity` exists in
1373- * blanket (like) implementation `impl` of `trait`, and the type at position
1374- * `posAdj` is `t`.
1373+ * blanket (like) implementation `impl` of `trait`, and the type at adjusted
1374+ * position `posAdj` is `t`.
13751375 *
13761376 * `blanketPath` points to the type `blanketTypeParam` inside `t`, which
13771377 * is the type parameter used in the blanket implementation.
13781378 */
13791379 pragma [ nomagic]
13801380 private predicate assocFunctionInfoBlanketLike (
1381- Function f , string name , int arity , ImplItemNode impl , Trait trait , FunctionPosition posAdj ,
1382- AssocFunctionType t , TypePath blanketPath , TypeParam blanketTypeParam
1381+ Function f , string name , int arity , ImplItemNode impl , TypeOption implType , TypeOption trait ,
1382+ FunctionPosition posAdj , AssocFunctionType t , TypePath blanketPath , TypeParam blanketTypeParam ,
1383+ boolean isMethod
13831384 ) {
13841385 exists ( TypePath blanketSelfPath |
1385- assocFunctionInfo ( f , name , arity , impl , posAdj , t ) and
1386+ assocFunctionInfo ( f , name , arity , posAdj , impl , t , _ , _ , implType , trait , isMethod ) and
13861387 TTypeParamTypeParameter ( blanketTypeParam ) = t .getTypeAt ( blanketPath ) and
13871388 blanketPath = any ( string s ) + blanketSelfPath and
1388- BlanketImplementation:: isBlanketLike ( impl , blanketSelfPath , blanketTypeParam ) and
1389- trait = impl .resolveTraitTy ( )
1389+ BlanketImplementation:: isBlanketLike ( impl , blanketSelfPath , blanketTypeParam )
13901390 )
13911391 }
13921392
13931393 /**
13941394 * Holds if the non-method trait function `f` mentions the implicit `Self` type
1395- * parameter at `posAdj`.
1395+ * parameter at adjusted position `posAdj`.
13961396 */
13971397 pragma [ nomagic]
13981398 private predicate traitSelfTypeParameterOccurrence (
@@ -1407,7 +1407,7 @@ private module AssocFunctionResolution {
14071407
14081408 /**
14091409 * Holds if the non-method function `f` implements a trait function that mentions
1410- * the implicit `Self` type parameter at `posAdj`.
1410+ * the implicit `Self` type parameter at adjusted position `posAdj`.
14111411 */
14121412 pragma [ nomagic]
14131413 private predicate traitImplSelfTypeParameterOccurrence (
@@ -1428,6 +1428,11 @@ private module AssocFunctionResolution {
14281428 * Holds if function `f` with the name `name` and the arity `arity` exists in
14291429 * `i`, and the type at `selfPosAdj` is `selfType`.
14301430 *
1431+ * `selfPosAdj` is an adjusted position relevant for call resolution: either a position
1432+ * corresponding to the `self` parameter of `f` (if present); a type qualifier position;
1433+ * or a position where the implicit `Self` type parameter of some trait is mentioned in
1434+ * some non-method function `f_trait`, and either `f = f_trait` or `f` implements `f_trait`.
1435+ *
14311436 * `strippedTypePath` points to the type `strippedType` inside `selfType`,
14321437 * which is the (possibly complex-stripped) root type of `selfType`. For example,
14331438 * if `f` has a `&self` parameter, then `strippedTypePath` is `getRefSharedTypeParameter()`
@@ -1511,19 +1516,32 @@ private module AssocFunctionResolution {
15111516 AssocFunctionTraitIsVisible:: traitIsVisible ( afc , impl .resolveTraitTy ( ) )
15121517 }
15131518
1514- pragma [ inline]
1515- private predicate callMatching (
1516- TypeOption implType , TypeOption trait , Boolean isMethod , TypeOption typeQualifier ,
1517- TypeOption traitQualifier , boolean hasReceiver
1518- ) {
1519+ bindingset [ implType]
1520+ private predicate callTypeQualifierFilter ( TypeOption implType , TypeOption typeQualifier ) {
15191521 // when present, explicit type qualifier must match the type being implemented
1520- typeQualifier = [ implType , any ( TypeOption non | non .isNone ( ) ) ] and
1522+ typeQualifier = [ implType , any ( TypeOption non | non .isNone ( ) ) ]
1523+ }
1524+
1525+ bindingset [ trait, isMethod]
1526+ pragma [ inline_late]
1527+ private predicate callTraitQualifierAndReceiverFilter (
1528+ TypeOption trait , Boolean isMethod , TypeOption traitQualifier , boolean hasReceiver
1529+ ) {
15211530 // when present, explicit trait qualifier must match the trait being implemented or the trait itself
15221531 traitQualifier = [ trait , any ( TypeOption non | non .isNone ( ) ) ] and
15231532 // when a receiver is present, the target must be a method
15241533 hasReceiver = [ isMethod , false ]
15251534 }
15261535
1536+ bindingset [ implType, trait, isMethod]
1537+ private predicate callFilter (
1538+ TypeOption implType , TypeOption trait , Boolean isMethod , TypeOption typeQualifier ,
1539+ TypeOption traitQualifier , boolean hasReceiver
1540+ ) {
1541+ callTypeQualifierFilter ( implType , typeQualifier ) and
1542+ callTraitQualifierAndReceiverFilter ( trait , isMethod , traitQualifier , hasReceiver )
1543+ }
1544+
15271545 pragma [ nomagic]
15281546 private predicate assocFunctionInfoNonBlanketLikeCand (
15291547 Function f , string name , int arity , FunctionPosition selfPosAdj , ImplOrTraitItemNode i ,
@@ -1534,7 +1552,7 @@ private module AssocFunctionResolution {
15341552 assocFunctionInfo ( f , name , arity , selfPosAdj , i , selfType , strippedTypePath , strippedType ,
15351553 implType , trait , isMethod ) and
15361554 not BlanketImplementation:: isBlanketLike ( i , _, _) and
1537- callMatching ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
1555+ callFilter ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
15381556 )
15391557 }
15401558
@@ -1548,7 +1566,7 @@ private module AssocFunctionResolution {
15481566 assocFunctionInfo ( f , name , arity , selfPosAdj , i , selfType , strippedTypePath ,
15491567 TTypeParamTypeParameter ( _) , implType , trait , isMethod ) and
15501568 not BlanketImplementation:: isBlanketLike ( i , _, _) and
1551- callMatching ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
1569+ callFilter ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
15521570 )
15531571 }
15541572
@@ -1586,17 +1604,14 @@ private module AssocFunctionResolution {
15861604 }
15871605
15881606 pragma [ nomagic]
1589- private predicate assocFunctionSelfInfoBlanketLikeCand (
1607+ private predicate assocFunctionSelfInfoBlanketLikeCand0 (
15901608 Function f , string name , int arity , FunctionPosition selfPosAdj , ImplItemNode impl ,
15911609 AssocFunctionType selfType , TypePath blanketPath , TypeParam blanketTypeParam ,
1592- TypeOption traitQualifier , boolean hasReceiver
1610+ TypeOption implType , TypeOption trait , boolean isMethod
15931611 ) {
1594- exists ( Trait trait , boolean isMethod |
1595- assocFunctionInfoBlanketLike ( f , name , arity , impl , trait , selfPosAdj , selfType , blanketPath ,
1596- blanketTypeParam ) and
1597- ( if f instanceof Method then isMethod = true else isMethod = false ) and
1598- callMatching ( _, TypeOption:: some ( TTrait ( trait ) ) , isMethod , _, traitQualifier , hasReceiver )
1599- |
1612+ assocFunctionInfoBlanketLike ( f , name , arity , impl , implType , trait , selfPosAdj , selfType ,
1613+ blanketPath , blanketTypeParam , isMethod ) and
1614+ (
16001615 isMethod = true and
16011616 selfPosAdj .asPosition ( ) = 0
16021617 or
@@ -1606,6 +1621,25 @@ private module AssocFunctionResolution {
16061621 )
16071622 }
16081623
1624+ bindingset [ name, arity, typeQualifier, traitQualifier, hasReceiver]
1625+ pragma [ inline_late]
1626+ private predicate assocFunctionSelfInfoBlanketLikeCand (
1627+ Function f , string name , int arity , FunctionPosition selfPosAdj , ImplItemNode impl ,
1628+ AssocFunctionType selfType , TypePath blanketPath , TypeParam blanketTypeParam ,
1629+ TypeOption typeQualifier , TypeOption traitQualifier , boolean hasReceiver
1630+ ) {
1631+ exists ( TypeOption implType , TypeOption trait , boolean isMethod |
1632+ assocFunctionSelfInfoBlanketLikeCand0 ( f , name , arity , selfPosAdj , impl , selfType , blanketPath ,
1633+ blanketTypeParam , implType , trait , isMethod ) and
1634+ (
1635+ if impl .isBlanketImplementation ( )
1636+ then any ( )
1637+ else callTypeQualifierFilter ( implType , typeQualifier )
1638+ ) and
1639+ callTraitQualifierAndReceiverFilter ( trait , isMethod , traitQualifier , hasReceiver )
1640+ )
1641+ }
1642+
16091643 /**
16101644 * Holds if call `afc` may target function `f` in blanket (like) implementation
16111645 * `impl` with type `selfType` at `selfPosAdj`.
@@ -1623,10 +1657,13 @@ private module AssocFunctionResolution {
16231657 AssocFunctionCall afc , Function f , FunctionPosition selfPosAdj , ImplItemNode impl ,
16241658 AssocFunctionType self , TypePath blanketPath , TypeParam blanketTypeParam
16251659 ) {
1626- exists ( string name , int arity , TypeOption traitQualifier , boolean hasReceiver |
1627- afc .hasSyntacticInfo ( name , arity , _, traitQualifier , hasReceiver ) and
1660+ exists (
1661+ string name , int arity , TypeOption typeQualifier , TypeOption traitQualifier ,
1662+ boolean hasReceiver
1663+ |
1664+ afc .hasSyntacticInfo ( name , arity , typeQualifier , traitQualifier , hasReceiver ) and
16281665 assocFunctionSelfInfoBlanketLikeCand ( f , name , arity , selfPosAdj , impl , self , blanketPath ,
1629- blanketTypeParam , traitQualifier , hasReceiver )
1666+ blanketTypeParam , typeQualifier , traitQualifier , hasReceiver )
16301667 |
16311668 if not afc .hasATrait ( ) then callVisibleImplTraitCandidate ( afc , impl ) else any ( )
16321669 )
0 commit comments