@@ -1407,7 +1407,9 @@ private module AssocFunctionResolution {
14071407 *
14081408 * `selfPosAdj` is the function-call adjusted version of `selfPos`.
14091409 *
1410- * `implType` is the type being implemented (`None` when `i` is a trait).
1410+ * `implType` is the type being implemented by `i` (`None` when `i` is a trait).
1411+ *
1412+ * `trait` is the trait being implemented by `i` or `i` itself (`None` when `i` is inherent).
14111413 *
14121414 * `isMethod` indicates whether `f` is a method.
14131415 */
@@ -1451,7 +1453,7 @@ private module AssocFunctionResolution {
14511453 }
14521454
14531455 pragma [ nomagic]
1454- private predicate assocFunctionInfoNonBlanketLike0 (
1456+ private predicate assocFunctionInfoNonBlanketLike (
14551457 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
14561458 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
14571459 TypeOption implType , TypeOption trait , boolean isMethod
@@ -1464,29 +1466,11 @@ private module AssocFunctionResolution {
14641466 pragma [ nomagic]
14651467 private predicate assocFunctionInfoNonBlanketLikeTypeParam (
14661468 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
1467- ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , TypeParam tp ,
1468- TypeOption implType , TypeOption trait , boolean isMethod
1469- ) {
1470- assocFunctionInfo ( f , name , arity , selfPos , selfPosAdj , i , selfType , strippedTypePath ,
1471- TTypeParamTypeParameter ( tp ) , implType , trait , isMethod ) and
1472- not BlanketImplementation:: isBlanketLike ( i , _, _)
1473- }
1474-
1475- /**
1476- * Same as `assocFunctionInfo`, but restricted to non-blanket-like implementations, and
1477- * allowing for any `strippedType` when the corresponding type inside `f` is
1478- * a type parameter.
1479- */
1480- pragma [ inline]
1481- private predicate assocFunctionInfoNonBlanketLike (
1482- Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
1483- ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
1469+ ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath ,
14841470 TypeOption implType , TypeOption trait , boolean isMethod
14851471 ) {
1486- assocFunctionInfoNonBlanketLike0 ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1487- strippedTypePath , strippedType , implType , trait , isMethod ) or
1488- assocFunctionInfoNonBlanketLikeTypeParam ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1489- strippedTypePath , _, implType , trait , isMethod )
1472+ assocFunctionInfoNonBlanketLike ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1473+ strippedTypePath , TTypeParamTypeParameter ( _) , implType , trait , isMethod )
14901474 }
14911475
14921476 /**
@@ -1496,6 +1480,8 @@ private module AssocFunctionResolution {
14961480 *
14971481 * `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which
14981482 * is the type parameter used in the blanket implementation.
1483+ *
1484+ * `isMethod` indicates whether `f` is a method.
14991485 */
15001486 pragma [ nomagic]
15011487 private predicate assocFunctionSelfInfoBlanketLike (
@@ -1531,14 +1517,14 @@ private module AssocFunctionResolution {
15311517 exists ( string name , int arity |
15321518 afc0 .hasNameAndArity ( name , arity ) and
15331519 assocFunctionTraitInfo ( name , arity , trait ) and
1520+ // we only need to check visibility of traits that are not mentioned explicitly
15341521 not afc0 .hasATrait ( )
15351522 )
15361523 )
15371524 }
15381525
15391526 private module AssocFunctionTraitIsVisible = TraitIsVisible< assocFunctionCallTraitCandidate / 2 > ;
15401527
1541- // private predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2;
15421528 bindingset [ afc, impl]
15431529 pragma [ inline_late]
15441530 private predicate callVisibleImplTraitCandidate ( AssocFunctionCall afc , ImplItemNode impl ) {
@@ -1571,6 +1557,45 @@ private module AssocFunctionResolution {
15711557 )
15721558 }
15731559
1560+ bindingset [ implType, trait, isMethod]
1561+ private predicate callMatching (
1562+ TypeOption implType , TypeOption trait , boolean isMethod , TypeOption typeQualifier ,
1563+ TypeOption traitQualifier , boolean hasReceiver
1564+ ) {
1565+ // when present, explicit type qualifier must match the type being implemented
1566+ typeQualifier = [ implType , any ( TypeOption non | non .isNone ( ) ) ] and
1567+ // when present, explicit trait qualifier must match the trait being implemented or the trait itself
1568+ traitQualifier = [ trait , any ( TypeOption non | non .isNone ( ) ) ] and
1569+ // when a receiver is present, the target must be a method
1570+ hasReceiver = [ isMethod , false ]
1571+ }
1572+
1573+ pragma [ nomagic]
1574+ private predicate assocFunctionInfoNonBlanketLikeCand (
1575+ Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
1576+ ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
1577+ TypeOption typeQualifier , TypeOption traitQualifier , boolean hasReceiver
1578+ ) {
1579+ exists ( TypeOption implType , TypeOption trait , boolean isMethod |
1580+ assocFunctionInfoNonBlanketLike ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1581+ strippedTypePath , strippedType , implType , trait , isMethod ) and
1582+ callMatching ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
1583+ )
1584+ }
1585+
1586+ pragma [ nomagic]
1587+ private predicate assocFunctionInfoNonBlanketLikeTypeParamCand (
1588+ Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
1589+ ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath ,
1590+ TypeOption typeQualifier , TypeOption traitQualifier , boolean hasReceiver
1591+ ) {
1592+ exists ( TypeOption implType , TypeOption trait , boolean isMethod |
1593+ assocFunctionInfoNonBlanketLikeTypeParam ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1594+ strippedTypePath , implType , trait , isMethod ) and
1595+ callMatching ( implType , trait , isMethod , typeQualifier , traitQualifier , hasReceiver )
1596+ )
1597+ }
1598+
15741599 /**
15751600 * Holds if call `afc` may target function `f` in `i` with type `selfType` at
15761601 * `selfPos`.
@@ -1588,15 +1613,20 @@ private module AssocFunctionResolution {
15881613 AssocFunctionCall afc , Function f , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
15891614 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType
15901615 ) {
1591- exists ( string name , int arity , TypeOption implType , TypeOption trait , boolean isMethod |
1592- callInfo ( afc , name , arity , [ implType , any ( TypeOption non | non .isNone ( ) ) ] ,
1593- [ trait , any ( TypeOption non | non .isNone ( ) ) ] , [ false , isMethod ] ) and
1594- assocFunctionInfoNonBlanketLike ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1595- strippedTypePath , strippedType , implType , trait , isMethod )
1616+ exists (
1617+ string name , int arity , TypeOption typeQualifier , TypeOption traitQualifier ,
1618+ boolean hasReceiver
15961619 |
1620+ callInfo ( afc , name , arity , typeQualifier , traitQualifier , hasReceiver ) and
15971621 if not afc .hasATrait ( ) and i .( Impl ) .hasTrait ( )
15981622 then callVisibleImplTraitCandidate ( afc , i )
15991623 else any ( )
1624+ |
1625+ assocFunctionInfoNonBlanketLikeCand ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1626+ strippedTypePath , strippedType , typeQualifier , traitQualifier , hasReceiver )
1627+ or
1628+ assocFunctionInfoNonBlanketLikeTypeParamCand ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1629+ strippedTypePath , typeQualifier , traitQualifier , hasReceiver )
16001630 )
16011631 }
16021632
@@ -2333,8 +2363,12 @@ private module AssocFunctionResolution {
23332363 |
23342364 this .hasSignature ( _, selfPosAdj , strippedTypePath , strippedType , name , arity ) and
23352365 forall ( Impl i |
2336- assocFunctionInfoNonBlanketLike ( _, name , arity , _, selfPosAdj , i , _, strippedTypePath ,
2337- strippedType , _, _, _) and
2366+ (
2367+ assocFunctionInfoNonBlanketLike ( _, name , arity , _, selfPosAdj , i , _, strippedTypePath ,
2368+ strippedType , _, _, _) or
2369+ assocFunctionInfoNonBlanketLikeTypeParam ( _, name , arity , _, selfPosAdj , i , _,
2370+ strippedTypePath , _, _, _)
2371+ ) and
23382372 i .isInherent ( )
23392373 |
23402374 this .hasIncompatibleInherentTarget ( i )
0 commit comments