@@ -838,10 +838,13 @@ private predicate functionInfoBlanket(
838838 Function f , string name , int arity , ImplItemNode impl , Trait trait , FunctionTypePosition pos ,
839839 FunctionType t , TypePath blanketPath , TypeParam blanketTypeParam
840840) {
841- functionInfo ( f , name , arity , impl , pos , t ) and
842- TTypeParamTypeParameter ( blanketTypeParam ) = t .getTypeAt ( blanketPath ) and
843- MethodResolution:: isBlanketLike ( impl , blanketTypeParam ) and
844- trait = impl .resolveTraitTy ( )
841+ exists ( TypePath path0 |
842+ functionInfo ( f , name , arity , impl , pos , t ) and
843+ TTypeParamTypeParameter ( blanketTypeParam ) = t .getTypeAt ( blanketPath ) and
844+ blanketPath = any ( string s ) + path0 and
845+ BlanketImplementation:: isBlanket ( impl , path0 , blanketTypeParam ) and
846+ trait = impl .resolveTraitTy ( )
847+ )
845848}
846849
847850/**
@@ -881,6 +884,30 @@ private module ArgIsInstantiationOf<
881884 }
882885}
883886
887+ /**
888+ * Holds if `root` is a valid complex [`self` root type][1], with type
889+ * parameter `tp`.
890+ *
891+ * [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html?highlight=self#r-items.associated.fn.method.self-ty
892+ */
893+ pragma [ nomagic]
894+ predicate complexSelfRoot ( Type root , TypeParameter tp ) {
895+ tp = root .( RefType ) .getPositionalTypeParameter ( _)
896+ or
897+ exists ( Struct s |
898+ root = TStruct ( s ) and
899+ tp = root .getPositionalTypeParameter ( 0 )
900+ |
901+ s instanceof BoxStruct
902+ or
903+ s instanceof RcStruct
904+ or
905+ s instanceof ArcStruct
906+ or
907+ s instanceof PinStruct
908+ )
909+ }
910+
884911/**
885912 * Provides logic for resolving calls to methods.
886913 *
@@ -916,30 +943,6 @@ private module ArgIsInstantiationOf<
916943 * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
917944 */
918945private module MethodResolution {
919- /**
920- * Holds if `root` is a valid complex [`self` root type][1], with type
921- * parameter `tp`.
922- *
923- * [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html?highlight=self#r-items.associated.fn.method.self-ty
924- */
925- pragma [ nomagic]
926- private predicate complexSelfRoot ( Type root , TypeParameter tp ) {
927- tp = root .( RefType ) .getPositionalTypeParameter ( _)
928- or
929- exists ( Struct s |
930- root = TStruct ( s ) and
931- tp = root .getPositionalTypeParameter ( 0 )
932- |
933- s instanceof BoxStruct
934- or
935- s instanceof RcStruct
936- or
937- s instanceof ArcStruct
938- or
939- s instanceof PinStruct
940- )
941- }
942-
943946 /**
944947 * Holds if the type path `path` pointing to `type` is stripped of any leading
945948 * complex root type allowed for `self` parameters, such as `&`, `Box`, `Rc`,
@@ -991,17 +994,6 @@ private module MethodResolution {
991994 methodInfo ( m , name , arity , i , selfType , strippedTypePath , TTypeParamTypeParameter ( tp ) )
992995 }
993996
994- predicate isBlanketLike ( ImplItemNode i , TypeParam tp ) {
995- tp = i .getBlanketImplementationTypeParam ( )
996- // or
997- // exists(TypeMention tm, Type root, TypeParameter tp0 |
998- // tm = i.(Impl).getSelfTy() and
999- // complexSelfRoot(root, tp0) and
1000- // tm.resolveType() = root and
1001- // tm.resolveTypeAt(TypePath::singleton(tp0)) = TTypeParamTypeParameter(tp)
1002- // )
1003- }
1004-
1005997 /**
1006998 * Same as `methodInfo`, but restricted to non-blanket implementations, and
1007999 * allowing for any `strippedType` when the corresponding type inside `m` is
@@ -1016,7 +1008,7 @@ private module MethodResolution {
10161008 methodInfo ( m , name , arity , i , selfType , strippedTypePath , strippedType ) or
10171009 methodInfoTypeParam ( m , name , arity , i , selfType , strippedTypePath , _)
10181010 ) and
1019- not isBlanketLike ( i , _)
1011+ not BlanketImplementation :: isBlanket ( i , _ , _)
10201012 }
10211013
10221014 /**
@@ -1242,7 +1234,7 @@ private module MethodResolution {
12421234 forall ( ImplOrTraitItemNode i |
12431235 methodCallNonBlanketCandidate ( this , _, i , _, strippedTypePath , strippedType )
12441236 or
1245- CallExprImpl :: getResolvedFunction ( this ) = i . ( ImplItemNode ) . getASuccessor ( _ )
1237+ this . ( MethodCallCallExpr ) . hasTypeQualifiedCandidate ( i )
12461238 |
12471239 this .hasIncompatibleTarget ( i , derefChainBorrow )
12481240 )
@@ -1265,7 +1257,7 @@ private module MethodResolution {
12651257 forall ( ImplOrTraitItemNode i |
12661258 methodCallNonBlanketCandidate ( this , _, i , _, strippedTypePath , strippedType )
12671259 or
1268- CallExprImpl :: getResolvedFunction ( this ) = i . ( ImplItemNode ) . getASuccessor ( _ )
1260+ this . ( MethodCallCallExpr ) . hasTypeQualifiedCandidate ( i )
12691261 |
12701262 this .hasIncompatibleTarget ( i , derefChainBorrow )
12711263 )
@@ -1371,6 +1363,20 @@ private module MethodResolution {
13711363 forall ( ItemNode i | i = CallExprImpl:: getResolvedFunction ( this ) | i instanceof Method )
13721364 }
13731365
1366+ /**
1367+ * Holds if this call has a type qualifier, and we are able to resolve,
1368+ * using path resolution, the function to a member of `impl`.
1369+ *
1370+ * When this is the case, we still want to check that the type qualifier
1371+ * is an instance of the type being implemented, which is done in
1372+ * `MethodCallCallExprIsInstantiationOfInput`.
1373+ */
1374+ pragma [ nomagic]
1375+ predicate hasTypeQualifiedCandidate ( ImplItemNode impl ) {
1376+ exists ( getCallExprTypeQualifier ( this , _) ) and
1377+ CallExprImpl:: getResolvedFunction ( this ) = impl .getASuccessor ( _)
1378+ }
1379+
13741380 pragma [ nomagic]
13751381 override predicate hasNameAndArity ( string name , int arity ) {
13761382 name = CallExprImpl:: getFunctionPath ( this ) .getText ( ) and
@@ -1492,14 +1498,19 @@ private module MethodResolution {
14921498 )
14931499 }
14941500
1501+ pragma [ nomagic]
1502+ private predicate argIsInstanceOf ( ImplOrTraitItemNode i ) {
1503+ IsInstantiationOf< MethodCallCallExpr , TypeMentionTypeTree , MethodCallCallExprIsInstantiationOfInput > :: isInstantiationOf ( mc_ ,
1504+ i , _)
1505+ }
1506+
14951507 pragma [ nomagic]
14961508 private predicate argIsInstanceOf ( ImplOrTraitItemNode i , string name , int arity ) {
14971509 (
14981510 ArgIsInstantiationOf< MethodCallCand , MethodCallReceiverIsInstantiationOfInput > :: argIsInstanceOf ( this ,
14991511 i , _)
15001512 or
1501- IsInstantiationOf< MethodCallCallExpr , TypeMentionTypeTree , MethodCallCallExprIsInstantiationOfInput > :: isInstantiationOf ( mc_ ,
1502- i , _)
1513+ this .argIsInstanceOf ( i )
15031514 ) and
15041515 mc_ .hasNameAndArity ( name , arity )
15051516 }
@@ -1553,11 +1564,11 @@ private module MethodResolution {
15531564 {
15541565 pragma [ nomagic]
15551566 predicate hasBlanketCandidate (
1556- MethodCallCand mcc , Function m , TypePath blanketPath , TypeParam blanketTypeParam
1567+ MethodCallCand mcc , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
15571568 ) {
15581569 exists ( MethodCall mc , string name , int arity |
15591570 mcc .hasSignature ( mc , _, _, name , arity ) and
1560- methodCallBlanketCandidate ( mc , m , _ , _, blanketPath , blanketTypeParam ) and
1571+ methodCallBlanketCandidate ( mc , _ , impl , _, blanketPath , blanketTypeParam ) and
15611572 // Only apply blanket implementations when no other implementations are possible;
15621573 // this is to account for codebases that use the (unstable) specialization feature
15631574 // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html)
@@ -1587,7 +1598,7 @@ private module MethodResolution {
15871598 or
15881599 methodCallBlanketCandidate ( mc , m , i , selfType , _, _) and
15891600 BlanketImplementation:: SatisfiesBlanketConstraint< MethodCallCand , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( mcc ,
1590- m )
1601+ i )
15911602 )
15921603 }
15931604
@@ -1620,8 +1631,7 @@ private module MethodResolution {
16201631 private predicate potentialInstantiationOf0 (
16211632 MethodCallCallExpr ce , ImplItemNode impl , TypeMentionTypeTree constraint
16221633 ) {
1623- exists ( getCallExprTypeQualifier ( ce , _) ) and
1624- CallExprImpl:: getResolvedFunction ( ce ) = impl .getASuccessor ( _) and
1634+ ce .hasTypeQualifiedCandidate ( impl ) and
16251635 constraint = impl .getSelfPath ( )
16261636 }
16271637
@@ -1634,7 +1644,7 @@ private module MethodResolution {
16341644 then
16351645 // inherent methods take precedence over trait methods, so only allow
16361646 // trait methods when there are no matching inherent methods
1637- MkMethodCallCand ( ce , "" ) .( MethodCallCand ) .hasNoInherentTarget ( )
1647+ MkMethodCallCand ( ce , _ ) .( MethodCallCand ) .hasNoInherentTarget ( )
16381648 else any ( )
16391649 }
16401650
@@ -1914,10 +1924,10 @@ private module AssocFunctionResolution {
19141924
19151925 pragma [ nomagic]
19161926 private predicate functionCallBlanketCandidate (
1917- AssocFunctionCall fc , AssocFunction f , FunctionTypePosition pos , TypePath blanketPath ,
1918- TypeParam blanketTypeParam
1927+ AssocFunctionCall fc , AssocFunction f , ImplItemNode impl , FunctionTypePosition pos ,
1928+ TypePath blanketPath , TypeParam blanketTypeParam
19191929 ) {
1920- exists ( string name , int arity , ImplItemNode impl , Trait trait , FunctionType t |
1930+ exists ( string name , int arity , Trait trait , FunctionType t |
19211931 fc .hasNameAndArity ( name , arity ) and
19221932 exists ( getTypeAt ( fc , pos , blanketPath ) ) and
19231933 functionInfoBlanketRelevantPos ( f , name , arity , impl , trait , pos , t , blanketPath ,
@@ -1928,7 +1938,7 @@ private module AssocFunctionResolution {
19281938
19291939 private newtype TAssocFunctionCallAndPos =
19301940 MkAssocFunctionCallAndPos ( AssocFunctionCall fc , FunctionTypePosition pos ) {
1931- functionCallBlanketCandidate ( fc , _, pos , _, _)
1941+ functionCallBlanketCandidate ( fc , _, _ , pos , _, _)
19321942 }
19331943
19341944 class AssocFunctionCallAndPos extends MkAssocFunctionCallAndPos {
@@ -1949,11 +1959,12 @@ private module AssocFunctionResolution {
19491959 {
19501960 pragma [ nomagic]
19511961 predicate hasBlanketCandidate (
1952- AssocFunctionCallAndPos fcp , Function f , TypePath blanketPath , TypeParam blanketTypeParam
1962+ AssocFunctionCallAndPos fcp , ImplItemNode impl , TypePath blanketPath ,
1963+ TypeParam blanketTypeParam
19531964 ) {
19541965 exists ( AssocFunctionCall fc , FunctionTypePosition pos |
19551966 fcp = MkAssocFunctionCallAndPos ( fc , pos ) and
1956- functionCallBlanketCandidate ( fc , f , pos , blanketPath , blanketTypeParam )
1967+ functionCallBlanketCandidate ( fc , _ , impl , pos , blanketPath , blanketTypeParam )
19571968 )
19581969 }
19591970 }
@@ -1969,11 +1980,11 @@ private module AssocFunctionResolution {
19691980 predicate potentialInstantiationOf (
19701981 AssocFunctionCallAndPos fcp , TypeAbstraction abs , FunctionType constraint
19711982 ) {
1972- exists ( Function f , FunctionTypePosition pos |
1983+ exists ( FunctionTypePosition pos |
19731984 BlanketImplementation:: SatisfiesBlanketConstraint< AssocFunctionCallAndPos , SatisfiesBlanketConstraintInput > :: satisfiesBlanketConstraint ( fcp ,
1974- f ) and
1985+ abs ) and
19751986 fcp = MkAssocFunctionCallAndPos ( _, pos ) and
1976- functionInfoBlanketRelevantPos ( f , _, _, abs , _, pos , constraint , _, _)
1987+ functionInfoBlanketRelevantPos ( _ , _, _, abs , _, pos , constraint , _, _)
19771988 )
19781989 }
19791990
@@ -3079,8 +3090,8 @@ module Debug {
30793090 Locatable getRelevantLocatable ( ) {
30803091 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
30813092 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
3082- filepath .matches ( "%/sqlx .rs" ) and
3083- startline = 246
3093+ filepath .matches ( "%/test_futures_io .rs" ) and
3094+ startline = 45
30843095 )
30853096 }
30863097
0 commit comments