@@ -1239,31 +1239,45 @@ private module MethodCallResolution {
12391239 strippedType = selfType .getTypeAt ( strippedTypePath ) and
12401240 isComplexRootStripped ( strippedTypePath , strippedType ) and
12411241 selfType .appliesTo ( m , pos , i ) and
1242- pos .isSelf ( ) and
1243- not i .( ImplItemNode ) .isBlanketImplementation ( )
1242+ pos .isSelf ( )
12441243 )
12451244 }
12461245
12471246 pragma [ nomagic]
12481247 predicate methodInfoTypeParam (
12491248 Function m , string name , int arity , ImplOrTraitItemNode i , FunctionType selfType ,
1250- TypePath strippedTypePath
1249+ TypePath strippedTypePath , TypeParam tp
12511250 ) {
1252- methodInfo ( m , name , arity , i , selfType , strippedTypePath , TTypeParamTypeParameter ( _ ) )
1251+ methodInfo ( m , name , arity , i , selfType , strippedTypePath , TTypeParamTypeParameter ( tp ) )
12531252 }
12541253
12551254 /**
12561255 * Same as `methodInfo`, but allows for any `strippedType` when the
12571256 * corresponding type inside `m` is a type parameter.
12581257 */
12591258 pragma [ inline]
1260- predicate methodInfoMatch (
1259+ predicate methodInfoNonBlanketMatch (
12611260 Function m , string name , int arity , ImplOrTraitItemNode i , FunctionType selfType ,
12621261 TypePath strippedTypePath , Type strippedType
12631262 ) {
1264- methodInfo ( m , name , arity , i , selfType , strippedTypePath , strippedType )
1265- or
1266- methodInfoTypeParam ( m , name , arity , i , selfType , strippedTypePath )
1263+ (
1264+ methodInfo ( m , name , arity , i , selfType , strippedTypePath , strippedType ) or
1265+ methodInfoTypeParam ( m , name , arity , i , selfType , strippedTypePath , _)
1266+ ) and
1267+ not i .( ImplItemNode ) .isBlanketImplementation ( )
1268+ }
1269+
1270+ /**
1271+ * Same as `methodInfo`, but allows for any `strippedType` when the
1272+ * corresponding type inside `m` is a type parameter.
1273+ */
1274+ pragma [ nomagic]
1275+ predicate methodInfoBlanketMatch (
1276+ Function m , string name , int arity , ImplItemNode i , FunctionType selfType , TypePath blanketPath ,
1277+ TypeParam blanketTypeParam
1278+ ) {
1279+ methodInfoTypeParam ( m , name , arity , i , selfType , blanketPath , blanketTypeParam ) and
1280+ blanketTypeParam = i .getBlanketImplementationTypeParam ( )
12671281 }
12681282
12691283 pragma [ nomagic]
@@ -1278,7 +1292,8 @@ private module MethodCallResolution {
12781292
12791293 pragma [ nomagic]
12801294 private predicate methodCallTraitCandidate ( Element mc , Trait trait ) {
1281- exists ( string name , int arity | mc .( MethodCall ) .hasNameAndArity ( name , arity ) |
1295+ exists ( string name , int arity |
1296+ mc .( MethodCall ) .hasNameAndArity ( name , arity ) and
12821297 methodTraitInfo ( name , arity , trait )
12831298 )
12841299 }
@@ -1306,19 +1321,19 @@ private module MethodCallResolution {
13061321 */
13071322 bindingset [ mc, strippedTypePath, strippedType]
13081323 pragma [ inline_late]
1309- private predicate methodCallCandidate (
1310- MethodCall mc , ImplOrTraitItemNode i , FunctionType self , TypePath strippedTypePath ,
1324+ private predicate methodCallNonBlanketCandidate (
1325+ MethodCall mc , Function m , ImplOrTraitItemNode i , FunctionType self , TypePath strippedTypePath ,
13111326 Type strippedType
13121327 ) {
13131328 exists ( string name , int arity |
13141329 mc .hasNameAndArity ( name , arity ) and
1315- methodInfoMatch ( _ , name , arity , i , self , strippedTypePath , strippedType )
1330+ methodInfoNonBlanketMatch ( m , name , arity , i , self , strippedTypePath , strippedType )
13161331 |
13171332 i =
13181333 any ( Impl impl |
13191334 not impl .hasTrait ( )
13201335 or
1321- methodCallVisibleImplTraitCandidate ( mc , i )
1336+ methodCallVisibleImplTraitCandidate ( mc , impl )
13221337 )
13231338 or
13241339 methodCallVisibleTraitCandidate ( mc , i )
@@ -1328,6 +1343,34 @@ private module MethodCallResolution {
13281343 )
13291344 }
13301345
1346+ /**
1347+ * Holds if method call `mc` may target a method in `i` with `self` parameter having
1348+ * type `selfType`.
1349+ *
1350+ * `strippedTypePath` points to the type `strippedType` inside `selfType`,
1351+ * which is the (possibly complex-stripped) root type of `selfType`.
1352+ *
1353+ * This predicate only checks for matching method names and arities, and whether
1354+ * the trait being implemented by `i` (when `i` is not a trait itself) is visible
1355+ * at `mc`.
1356+ */
1357+ bindingset [ mc]
1358+ pragma [ inline_late]
1359+ private predicate methodCallBlanketCandidate (
1360+ MethodCall mc , Function m , ImplItemNode i , FunctionType self , TypePath blanketPath ,
1361+ TypeParam blanketTypeParam
1362+ ) {
1363+ exists ( string name , int arity |
1364+ mc .hasNameAndArity ( name , arity ) and
1365+ methodInfoBlanketMatch ( m , name , arity , i , self , blanketPath , blanketTypeParam )
1366+ |
1367+ methodCallVisibleImplTraitCandidate ( mc , i )
1368+ or
1369+ mc instanceof IndexExpr and
1370+ i .resolveTraitTy ( ) instanceof IndexTrait
1371+ )
1372+ }
1373+
13311374 /**
13321375 * A method call.
13331376 *
@@ -1408,7 +1451,7 @@ private module MethodCallResolution {
14081451 strippedType = this .getComplexstrippedType ( strippedTypePath , derefChainBorrow )
14091452 |
14101453 forall ( ImplOrTraitItemNode i |
1411- methodCallCandidate ( this , i , _, strippedTypePath , strippedType )
1454+ methodCallNonBlanketCandidate ( this , _ , i , _, strippedTypePath , strippedType )
14121455 |
14131456 this .hasIncompatibleTarget ( i , derefChainBorrow )
14141457 )
@@ -1427,7 +1470,7 @@ private module MethodCallResolution {
14271470 strippedType = this .getComplexstrippedType ( strippedTypePath , derefChainBorrow )
14281471 |
14291472 forall ( ImplOrTraitItemNode i |
1430- methodCallCandidate ( this , i , _, strippedTypePath , strippedType )
1473+ methodCallNonBlanketCandidate ( this , _ , i , _, strippedTypePath , strippedType )
14311474 |
14321475 this .hasIncompatibleTarget ( i , derefChainBorrow )
14331476 )
@@ -1473,7 +1516,9 @@ private module MethodCallResolution {
14731516 */
14741517 pragma [ nomagic]
14751518 Function resolveCallTarget ( string derefChainBorrow ) {
1476- result = MkMethodCallCand ( this , derefChainBorrow ) .( MethodCallCand ) .resolveCallTarget ( )
1519+ exists ( MethodCallCand mcc | mcc = MkMethodCallCand ( this , derefChainBorrow ) |
1520+ result = mcc .resolveCallTarget ( )
1521+ )
14771522 }
14781523
14791524 predicate receiverHasImplicitDeref ( AstNode receiver ) {
@@ -1561,11 +1606,11 @@ private module MethodCallResolution {
15611606 * resolve to a method in an `impl` block for the type of the receiver.
15621607 */
15631608 pragma [ nomagic]
1564- private predicate hasNoInherentTarget ( ) {
1609+ predicate hasNoInherentTarget ( ) {
15651610 exists ( TypePath strippedTypePath , Type strippedType , string name , int arity |
15661611 this .hasInfo ( _, strippedTypePath , strippedType , name , arity ) and
15671612 forall ( Impl i |
1568- methodInfoMatch ( _, name , arity , i , _, strippedTypePath , strippedType ) and
1613+ methodInfoNonBlanketMatch ( _, name , arity , i , _, strippedTypePath , strippedType ) and
15691614 not i .hasTrait ( )
15701615 |
15711616 this .hasIncompatibleInherentTarget ( i )
@@ -1627,6 +1672,88 @@ private module MethodCallResolution {
16271672 Location getLocation ( ) { result = mc_ .getLocation ( ) }
16281673 }
16291674
1675+ private newtype TMethodCallCandAndBlanketOffset =
1676+ MkMethodCallCandAndBlanketOffset ( MethodCallCand mcc , TypePath blanketPath ) {
1677+ exists ( MethodCall mc , string name , int arity , TypeParam blanketTypeParam |
1678+ mcc .hasInfo ( mc , _, _, name , arity ) and
1679+ methodCallBlanketCandidate ( mc , _, _, _, blanketPath , blanketTypeParam )
1680+ )
1681+ }
1682+
1683+ private class MethodCallCandAndBlanketOffset extends MkMethodCallCandAndBlanketOffset {
1684+ MethodCallCand mcc_ ;
1685+ TypePath blanketPath ;
1686+
1687+ MethodCallCandAndBlanketOffset ( ) { this = MkMethodCallCandAndBlanketOffset ( mcc_ , blanketPath ) }
1688+
1689+ MethodCallCand getMethodCallCand ( ) { result = mcc_ }
1690+
1691+ TypePath getBlanketPath ( ) { result = blanketPath }
1692+
1693+ Location getLocation ( ) { result = mcc_ .getLocation ( ) }
1694+
1695+ Type getTypeAt ( TypePath path ) { result = mcc_ .getTypeAt ( blanketPath .appendInverse ( path ) ) }
1696+
1697+ string toString ( ) { result = mcc_ .toString ( ) + " (blanket at " + blanketPath .toString ( ) + ")" }
1698+ }
1699+
1700+ private module SatisfiesBlanketConstraintInput implements
1701+ SatisfiesConstraintInputSig< MethodCallCandAndBlanketOffset >
1702+ {
1703+ /**
1704+ * Holds if `impl` is a blanket implementation for a type parameter and
1705+ * `traitBound` is the first non-trivial trait bound of that type parameter.
1706+ */
1707+ pragma [ nomagic]
1708+ private predicate blanketImplementationTraitBound ( TypeParamItemNode tp , Trait traitBound ) {
1709+ tp = any ( ImplItemNode impl ) .getBlanketImplementationTypeParam ( ) and
1710+ traitBound =
1711+ min ( Trait trait , int i |
1712+ trait = tp .resolveBound ( i ) and
1713+ // Exclude traits that are known to not narrow things down very much.
1714+ not trait .getName ( ) .getText ( ) =
1715+ [
1716+ "Sized" , "Clone" ,
1717+ // The auto traits
1718+ "Send" , "Sync" , "Unpin" , "UnwindSafe" , "RefUnwindSafe"
1719+ ]
1720+ |
1721+ trait order by i
1722+ )
1723+ }
1724+
1725+ pragma [ nomagic]
1726+ additional predicate relevantConstraint (
1727+ MethodCallCandAndBlanketOffset mcco , Function m , Trait traitBound
1728+ ) {
1729+ exists (
1730+ MethodCallCand mcc , MethodCall mc , string name , int arity , TypePath blanketPath ,
1731+ TypeParam blanketTypeParam
1732+ |
1733+ mcco = MkMethodCallCandAndBlanketOffset ( mcc , blanketPath ) and
1734+ mcc .hasInfo ( mc , _, _, name , arity ) and
1735+ methodCallBlanketCandidate ( mc , m , _, _, blanketPath , blanketTypeParam ) and
1736+ blanketImplementationTraitBound ( blanketTypeParam , traitBound )
1737+ )
1738+ }
1739+
1740+ pragma [ nomagic]
1741+ predicate relevantConstraint ( MethodCallCandAndBlanketOffset mcco , Type constraint ) {
1742+ relevantConstraint ( mcco , _, constraint .( TraitType ) .getTrait ( ) )
1743+ }
1744+
1745+ predicate useUniversalConditions ( ) { none ( ) }
1746+ }
1747+
1748+ private predicate hasBlanketImpl ( MethodCallCand mcc , Function f ) {
1749+ exists ( MethodCallCandAndBlanketOffset mcco , Trait traitBound |
1750+ mcco = MkMethodCallCandAndBlanketOffset ( mcc , _) and
1751+ SatisfiesBlanketConstraintInput:: relevantConstraint ( mcco , f , traitBound ) and
1752+ SatisfiesConstraint< MethodCallCandAndBlanketOffset , SatisfiesBlanketConstraintInput > :: satisfiesConstraintType ( mcco ,
1753+ TTrait ( traitBound ) , _, _)
1754+ )
1755+ }
1756+
16301757 /**
16311758 * A configuration for matching the type of a receiver against the type of
16321759 * a `self` parameter.
@@ -1638,9 +1765,16 @@ private module MethodCallResolution {
16381765 predicate potentialInstantiationOf (
16391766 MethodCallCand mcc , TypeAbstraction abs , FunctionType constraint
16401767 ) {
1641- exists ( MethodCall mc , string name , int arity , TypePath strippedTypePath , Type strippedType |
1642- mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity ) and
1643- methodCallCandidate ( mc , abs , constraint , strippedTypePath , strippedType )
1768+ exists (
1769+ MethodCall mc , Function m , string name , int arity , TypePath strippedTypePath ,
1770+ Type strippedType
1771+ |
1772+ mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity )
1773+ |
1774+ methodCallNonBlanketCandidate ( mc , m , abs , constraint , strippedTypePath , strippedType )
1775+ or
1776+ methodCallBlanketCandidate ( mc , m , abs , constraint , _, _) and
1777+ hasBlanketImpl ( mcc , m )
16441778 )
16451779 }
16461780
@@ -1981,20 +2115,23 @@ private module FunctionCallResolution {
19812115 TypePath strippedTypePath , Type strippedType , TraitItemNode trait , Function f ,
19822116 Function traitFunction
19832117 ) {
1984- MethodCallResolution:: methodInfo ( f , _, _, _, _, strippedTypePath , strippedType ) and
1985- traitFunction = trait .getAnAssocItem ( ) and
1986- (
1987- f .implements ( traitFunction )
1988- or
1989- f = traitFunction
2118+ exists ( ImplOrTraitItemNode i |
2119+ MethodCallResolution:: methodInfo ( f , _, _, i , _, strippedTypePath , strippedType ) and
2120+ not i .( ImplItemNode ) .isBlanketImplementation ( ) and
2121+ traitFunction = trait .getAnAssocItem ( ) and
2122+ (
2123+ f .implements ( traitFunction )
2124+ or
2125+ f = traitFunction
2126+ )
19902127 )
19912128 }
19922129
19932130 pragma [ nomagic]
19942131 private predicate methodInfoTypeParam (
19952132 TypePath strippedTypePath , TraitItemNode trait , Function f , Function traitFunction
19962133 ) {
1997- MethodCallResolution:: methodInfoTypeParam ( f , _, _, _, _, strippedTypePath ) and
2134+ MethodCallResolution:: methodInfoTypeParam ( f , _, _, _, _, strippedTypePath , _ ) and
19982135 traitFunction = trait .getAnAssocItem ( ) and
19992136 (
20002137 f .implements ( traitFunction )
@@ -2274,13 +2411,15 @@ private module OperationResolution {
22742411 private module OperationIsInstantiationOfInput implements
22752412 IsInstantiationOfInputSig< Op , FunctionType >
22762413 {
2277- pragma [ inline]
2278- private predicate methodInfoMatch (
2414+ // todo
2415+ bindingset [ strippedTypePath]
2416+ private predicate methodInfoNonBlanketMatch (
22792417 TypeAbstraction abs , FunctionType constraint , Trait trait , string name , int arity ,
22802418 TypePath strippedTypePath , Type strippedType
22812419 ) {
2282- MethodCallResolution:: methodInfoMatch ( _, name , arity , abs , constraint , strippedTypePath ,
2283- strippedType ) and
2420+ MethodCallResolution:: methodInfoNonBlanketMatch ( _, name , arity , abs , constraint ,
2421+ strippedTypePath , strippedType ) and
2422+ not abs .( ImplItemNode ) .isBlanketImplementation ( ) and
22842423 (
22852424 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
22862425 or
@@ -2292,7 +2431,8 @@ private module OperationResolution {
22922431 predicate potentialInstantiationOf ( Op op , TypeAbstraction abs , FunctionType constraint ) {
22932432 exists ( Trait trait , string name , int arity , TypePath strippedTypePath , Type strippedType |
22942433 op .hasInfo ( strippedTypePath , strippedType , trait , name , arity ) and
2295- methodInfoMatch ( abs , constraint , trait , name , arity , strippedTypePath , strippedType )
2434+ methodInfoNonBlanketMatch ( abs , constraint , trait , name , arity , strippedTypePath ,
2435+ strippedType )
22962436 )
22972437 }
22982438
0 commit comments