@@ -1221,28 +1221,6 @@ private module MethodCallResolution {
12211221 )
12221222 }
12231223
1224- /**
1225- * Holds if method `m` with the name `name` and the arity `arity` exists in
1226- * `i`, and the type of the `self` parameter is `selfType`.
1227- *
1228- * `strippedTypePath` points to the type `strippedType` inside `selfType`,
1229- * which is the (possibly complex-stripped) root type of `selfType`.
1230- */
1231- pragma [ nomagic]
1232- private predicate methodInfo0 (
1233- Function m , string name , int arity , ImplOrTraitItemNode i , FunctionType selfType ,
1234- TypePath strippedTypePath , Type strippedType
1235- ) {
1236- exists ( FunctionTypePosition pos |
1237- m = i .getASuccessor ( name ) and
1238- arity = m .getParamList ( ) .getNumberOfParams ( ) and
1239- strippedType = selfType .getTypeAt ( strippedTypePath ) and
1240- isComplexRootStripped ( strippedTypePath , strippedType ) and
1241- selfType .appliesTo ( m , pos , i ) and
1242- pos .isSelf ( )
1243- )
1244- }
1245-
12461224 /**
12471225 * Holds if method `m` with the name `name` and the arity `arity` exists in
12481226 * `i`, and the type of the `self` parameter is `selfType`.
@@ -1261,41 +1239,55 @@ private module MethodCallResolution {
12611239 strippedType = selfType .getTypeAt ( strippedTypePath ) and
12621240 isComplexRootStripped ( strippedTypePath , strippedType ) and
12631241 selfType .appliesTo ( m , pos , i ) and
1264- pos .isSelf ( ) and
1265- not i .( ImplItemNode ) .isBlanketImplementation ( )
1242+ pos .isSelf ( )
12661243 )
12671244 }
12681245
12691246 pragma [ nomagic]
12701247 predicate methodInfoTypeParam (
12711248 Function m , string name , int arity , ImplOrTraitItemNode i , FunctionType selfType ,
1272- TypePath strippedTypePath
1249+ TypePath strippedTypePath , TypeParam tp
12731250 ) {
1274- methodInfo ( m , name , arity , i , selfType , strippedTypePath , TTypeParamTypeParameter ( _ ) )
1251+ methodInfo ( m , name , arity , i , selfType , strippedTypePath , TTypeParamTypeParameter ( tp ) )
12751252 }
12761253
1254+ private import codeql.util.Option
1255+
1256+ private class TypeParamOption = Option< TypeParam > :: Option ;
1257+
12771258 /**
12781259 * Same as `methodInfo`, but allows for any `strippedType` when the
12791260 * corresponding type inside `m` is a type parameter.
12801261 */
1281- pragma [ inline ]
1262+ bindingset [ strippedTypePath ]
12821263 predicate methodInfoMatch (
12831264 Function m , string name , int arity , ImplOrTraitItemNode i , FunctionType selfType ,
1284- TypePath strippedTypePath , Type strippedType
1265+ TypePath strippedTypePath , Type strippedType , TypePath blanketPath ,
1266+ TypeParamOption blanketTypeParam
12851267 ) {
1286- methodInfo ( m , name , arity , i , selfType , strippedTypePath , strippedType )
1287- or
1288- methodInfoTypeParam ( m , name , arity , i , selfType , strippedTypePath )
1268+ (
1269+ methodInfo ( m , name , arity , i , selfType , strippedTypePath , strippedType ) or
1270+ methodInfoTypeParam ( m , name , arity , i , selfType , strippedTypePath , _)
1271+ ) and
1272+ not i .( ImplItemNode ) .isBlanketImplementation ( ) and
1273+ blanketPath = "" and
1274+ blanketTypeParam .isNone ( )
1275+ or
1276+ exists ( TypeParam tp |
1277+ methodInfoTypeParam ( m , name , arity , i , selfType , blanketPath , tp ) and
1278+ tp = blanketTypeParam .asSome ( ) and
1279+ tp = i .( ImplItemNode ) .getBlanketImplementationTypeParam ( )
1280+ )
12891281 }
12901282
12911283 pragma [ nomagic]
12921284 private predicate methodTraitInfo ( string name , int arity , Trait trait ) {
12931285 exists ( ImplItemNode i |
1294- methodInfo0 ( _, name , arity , i , _, _, _) and
1286+ methodInfo ( _, name , arity , i , _, _, _) and
12951287 trait = i .resolveTraitTy ( )
12961288 )
12971289 or
1298- methodInfo0 ( _, name , arity , trait , _, _, _)
1290+ methodInfo ( _, name , arity , trait , _, _, _)
12991291 }
13001292
13011293 pragma [ nomagic]
@@ -1330,12 +1322,13 @@ private module MethodCallResolution {
13301322 bindingset [ mc, strippedTypePath, strippedType]
13311323 pragma [ inline_late]
13321324 private predicate methodCallCandidate (
1333- MethodCall mc , ImplOrTraitItemNode i , FunctionType self , TypePath strippedTypePath ,
1334- Type strippedType
1325+ MethodCall mc , Function m , ImplOrTraitItemNode i , FunctionType self , TypePath strippedTypePath ,
1326+ Type strippedType , TypePath blanketPath , TypeParamOption blanketTypeParam
13351327 ) {
13361328 exists ( string name , int arity |
13371329 mc .hasNameAndArity ( name , arity ) and
1338- methodInfoMatch ( _, name , arity , i , self , strippedTypePath , strippedType )
1330+ methodInfoMatch ( m , name , arity , i , self , strippedTypePath , strippedType , blanketPath ,
1331+ blanketTypeParam )
13391332 |
13401333 i =
13411334 any ( Impl impl |
@@ -1430,8 +1423,9 @@ private module MethodCallResolution {
14301423 not derefChain .matches ( "%.ref" ) and // no need to try a borrow if the last thing we did was a deref
14311424 strippedType = this .getComplexstrippedType ( strippedTypePath , derefChainBorrow )
14321425 |
1433- forall ( ImplOrTraitItemNode i |
1434- methodCallCandidate ( this , i , _, strippedTypePath , strippedType )
1426+ forall ( ImplOrTraitItemNode i , TypeParamOption blanketTypeParam |
1427+ methodCallCandidate ( this , _, i , _, strippedTypePath , strippedType , _, blanketTypeParam ) and
1428+ blanketTypeParam .isNone ( )
14351429 |
14361430 this .hasIncompatibleTarget ( i , derefChainBorrow )
14371431 )
@@ -1449,8 +1443,9 @@ private module MethodCallResolution {
14491443 this .hasNoCompatibleTargetNoBorrow ( derefChain ) and
14501444 strippedType = this .getComplexstrippedType ( strippedTypePath , derefChainBorrow )
14511445 |
1452- forall ( ImplOrTraitItemNode i |
1453- methodCallCandidate ( this , i , _, strippedTypePath , strippedType )
1446+ forall ( ImplOrTraitItemNode i , TypeParamOption blanketTypeParam |
1447+ methodCallCandidate ( this , _, i , _, strippedTypePath , strippedType , _, blanketTypeParam ) and
1448+ blanketTypeParam .isNone ( )
14541449 |
14551450 this .hasIncompatibleTarget ( i , derefChainBorrow )
14561451 )
@@ -1590,7 +1585,7 @@ private module MethodCallResolution {
15901585 exists ( TypePath strippedTypePath , Type strippedType , string name , int arity |
15911586 this .hasInfo ( _, strippedTypePath , strippedType , name , arity ) and
15921587 forall ( Impl i |
1593- methodInfoMatch ( _, name , arity , i , _, strippedTypePath , strippedType ) and
1588+ methodInfoMatch ( _, name , arity , i , _, strippedTypePath , strippedType , _ , _ ) and
15941589 not i .hasTrait ( )
15951590 |
15961591 this .hasIncompatibleInherentTarget ( i )
@@ -1645,15 +1640,108 @@ private module MethodCallResolution {
16451640 result = this .resolveAmbigousCallTargetCand ( pos , path , type ) and
16461641 type = this .inferPositionalArgumentType ( pos , path )
16471642 )
1648- or
1649- result = BlanketImplementation:: getMethodFromBlanketImpl ( this )
1643+ // or
1644+ // result = BlanketImplementation::getMethodFromBlanketImpl(this)
16501645 }
16511646
16521647 string toString ( ) { result = mc_ .toString ( ) + " [" + derefChainBorrow + "]" }
16531648
16541649 Location getLocation ( ) { result = mc_ .getLocation ( ) }
16551650 }
16561651
1652+ private newtype TMethodCallCandAndBlanketOffset =
1653+ MkMethodCallCandAndBlanketOffset ( MethodCallCand mcc , TypePath blanketPath ) {
1654+ exists (
1655+ MethodCall mc , string name , int arity , TypePath strippedTypePath , Type strippedType ,
1656+ TypeParamOption blanketTypeParam
1657+ |
1658+ mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity ) and
1659+ methodCallCandidate ( mc , _, _, _, strippedTypePath , strippedType , blanketPath ,
1660+ blanketTypeParam ) and
1661+ blanketTypeParam .isSome ( )
1662+ )
1663+ }
1664+
1665+ private class MethodCallCandAndBlanketOffset extends MkMethodCallCandAndBlanketOffset {
1666+ MethodCallCand mcc_ ;
1667+ TypePath blanketPath ;
1668+
1669+ MethodCallCandAndBlanketOffset ( ) { this = MkMethodCallCandAndBlanketOffset ( mcc_ , blanketPath ) }
1670+
1671+ MethodCallCand getMethodCallCand ( ) { result = mcc_ }
1672+
1673+ TypePath getBlanketPath ( ) { result = blanketPath }
1674+
1675+ Location getLocation ( ) { result = mcc_ .getLocation ( ) }
1676+
1677+ Type getTypeAt ( TypePath path ) { result = mcc_ .getTypeAt ( blanketPath .appendInverse ( path ) ) }
1678+
1679+ string toString ( ) { result = mcc_ .toString ( ) + " (blanket at " + blanketPath .toString ( ) + ")" }
1680+ }
1681+
1682+ private module SatisfiesBlanketConstraintInput implements
1683+ SatisfiesConstraintInputSig< MethodCallCandAndBlanketOffset >
1684+ {
1685+ /**
1686+ * Holds if `impl` is a blanket implementation for a type parameter and
1687+ * `traitBound` is the first non-trivial trait bound of that type parameter.
1688+ */
1689+ pragma [ nomagic]
1690+ private predicate blanketImplementationTraitBound ( TypeParamItemNode tp , Trait traitBound ) {
1691+ tp = any ( ImplItemNode impl ) .getBlanketImplementationTypeParam ( ) and
1692+ traitBound =
1693+ min ( Trait trait , int i |
1694+ trait = tp .resolveBound ( i ) and
1695+ // Exclude traits that are known to not narrow things down very much.
1696+ not trait .getName ( ) .getText ( ) =
1697+ [
1698+ "Sized" , "Clone" ,
1699+ // The auto traits
1700+ "Send" , "Sync" , "Unpin" , "UnwindSafe" , "RefUnwindSafe"
1701+ ]
1702+ |
1703+ trait order by i
1704+ )
1705+ }
1706+
1707+ pragma [ nomagic]
1708+ additional predicate relevantConstraint (
1709+ MethodCallCandAndBlanketOffset mcco , Function m , Trait traitBound
1710+ ) {
1711+ exists (
1712+ MethodCallCand mcc , MethodCall mc , string name , int arity , TypePath strippedTypePath ,
1713+ Type strippedType , TypePath blanketPath , TypeParamOption blanketTypeParam
1714+ |
1715+ mcco = MkMethodCallCandAndBlanketOffset ( mcc , blanketPath ) and
1716+ mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity ) and
1717+ methodCallCandidate ( mc , m , _, _, strippedTypePath , strippedType , blanketPath ,
1718+ blanketTypeParam ) and
1719+ blanketImplementationTraitBound ( blanketTypeParam .asSome ( ) , traitBound )
1720+ )
1721+ // exists(MethodCall mc, Trait traitBound, Trait traitImpl |
1722+ // methodCallMatchesBlanketImpl(mcc, mc, _, _, traitBound, traitImpl, _) and
1723+ // methodCallVisibleTraitCandidate(mc, traitImpl) and
1724+ // traitBound = constraint.(TraitType).getTrait()
1725+ // )
1726+ }
1727+
1728+ pragma [ nomagic]
1729+ predicate relevantConstraint ( MethodCallCandAndBlanketOffset mcco , Type constraint ) {
1730+ relevantConstraint ( mcco , _, constraint .( TraitType ) .getTrait ( ) )
1731+ }
1732+
1733+ predicate useUniversalConditions ( ) { none ( ) }
1734+ }
1735+
1736+ private predicate hasBlanketImpl ( MethodCallCand mcc , Function f ) {
1737+ exists ( MethodCallCandAndBlanketOffset mcco , Trait traitBound |
1738+ mcco = MkMethodCallCandAndBlanketOffset ( mcc , _) and
1739+ SatisfiesBlanketConstraintInput:: relevantConstraint ( mcco , f , traitBound ) and
1740+ SatisfiesConstraint< MethodCallCandAndBlanketOffset , SatisfiesBlanketConstraintInput > :: satisfiesConstraintType ( mcco ,
1741+ TTrait ( traitBound ) , _, _)
1742+ )
1743+ }
1744+
16571745 /**
16581746 * A configuration for matching the type of a receiver against the type of
16591747 * a `self` parameter.
@@ -1665,9 +1753,17 @@ private module MethodCallResolution {
16651753 predicate potentialInstantiationOf (
16661754 MethodCallCand mcc , TypeAbstraction abs , FunctionType constraint
16671755 ) {
1668- exists ( MethodCall mc , string name , int arity , TypePath strippedTypePath , Type strippedType |
1756+ exists (
1757+ MethodCall mc , Function m , string name , int arity , TypePath strippedTypePath ,
1758+ Type strippedType , TypePath blanketPath , TypeParamOption blanketTypeParam
1759+ |
16691760 mcc .hasInfo ( mc , strippedTypePath , strippedType , name , arity ) and
1670- methodCallCandidate ( mc , abs , constraint , strippedTypePath , strippedType )
1761+ methodCallCandidate ( mc , m , abs , constraint , strippedTypePath , strippedType , blanketPath ,
1762+ blanketTypeParam )
1763+ |
1764+ blanketTypeParam .isNone ( )
1765+ or
1766+ hasBlanketImpl ( mcc , m )
16711767 )
16721768 }
16731769
@@ -2137,20 +2233,23 @@ private module FunctionCallResolution {
21372233 TypePath strippedTypePath , Type strippedType , TraitItemNode trait , Function f ,
21382234 Function traitFunction
21392235 ) {
2140- MethodCallResolution:: methodInfo ( f , _, _, _, _, strippedTypePath , strippedType ) and
2141- traitFunction = trait .getAnAssocItem ( ) and
2142- (
2143- f .implements ( traitFunction )
2144- or
2145- f = traitFunction
2236+ exists ( ImplOrTraitItemNode i |
2237+ MethodCallResolution:: methodInfo ( f , _, _, i , _, strippedTypePath , strippedType ) and
2238+ not i .( ImplItemNode ) .isBlanketImplementation ( ) and
2239+ traitFunction = trait .getAnAssocItem ( ) and
2240+ (
2241+ f .implements ( traitFunction )
2242+ or
2243+ f = traitFunction
2244+ )
21462245 )
21472246 }
21482247
21492248 pragma [ nomagic]
21502249 private predicate methodInfoTypeParam (
21512250 TypePath strippedTypePath , TraitItemNode trait , Function f , Function traitFunction
21522251 ) {
2153- MethodCallResolution:: methodInfoTypeParam ( f , _, _, _, _, strippedTypePath ) and
2252+ MethodCallResolution:: methodInfoTypeParam ( f , _, _, _, _, strippedTypePath , _ ) and
21542253 traitFunction = trait .getAnAssocItem ( ) and
21552254 (
21562255 f .implements ( traitFunction )
@@ -2430,13 +2529,15 @@ private module OperationResolution {
24302529 private module OperationIsInstantiationOfInput implements
24312530 IsInstantiationOfInputSig< Op , FunctionType >
24322531 {
2433- pragma [ inline]
2532+ // todo
2533+ bindingset [ strippedTypePath]
24342534 private predicate methodInfoMatch (
24352535 TypeAbstraction abs , FunctionType constraint , Trait trait , string name , int arity ,
24362536 TypePath strippedTypePath , Type strippedType
24372537 ) {
24382538 MethodCallResolution:: methodInfoMatch ( _, name , arity , abs , constraint , strippedTypePath ,
2439- strippedType ) and
2539+ strippedType , _, _) and
2540+ not abs .( ImplItemNode ) .isBlanketImplementation ( ) and
24402541 (
24412542 trait = abs .( ImplItemNode ) .resolveTraitTy ( )
24422543 or
0 commit comments