@@ -1385,6 +1385,38 @@ private module MethodResolution {
13851385 )
13861386 }
13871387
1388+ /**
1389+ * Holds if resolving the function `implFunction` in `impl` requires inspecting
1390+ * the type of applied _arguments_ or possibly knowing the return type.
1391+ *
1392+ * `traitTp` is a type parameter of the trait being implemented by `impl`, and
1393+ * we need to check that the type of `f` corresponding to `traitTp` is satisfied
1394+ * at any one of the positions `pos` in which that type occurs in `f` (at `path`).
1395+ *
1396+ * As for method resolution, we always check the type being implemented (corresponding
1397+ * to `traitTp` being the special `Self` type parameter).
1398+ */
1399+ pragma [ nomagic]
1400+ private predicate traitFunctionResolutionDependsOnArgument (
1401+ TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , ImplItemNode impl ,
1402+ NonMethodFunction implFunction , TypePath path , TypeParameter traitTp
1403+ ) {
1404+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos , impl , implFunction , path ,
1405+ traitTp ) and
1406+ // Exclude functions where we cannot resolve all relevant type mentions; this allows
1407+ // for blanket implementations to be applied in those cases
1408+ forall ( TypeParameter traitTp0 |
1409+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , _, impl , implFunction , _,
1410+ traitTp0 )
1411+ |
1412+ exists ( FunctionPosition pos0 , TypePath path0 |
1413+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos0 , impl , implFunction ,
1414+ path0 , traitTp0 ) and
1415+ exists ( getAssocFunctionTypeAt ( implFunction , impl , pos0 , path0 ) )
1416+ )
1417+ )
1418+ }
1419+
13881420 /**
13891421 * Holds if function `f` with the name `name` and the arity `arity` exists in
13901422 * `i`, and the type of the `self` parameter is `selfType`.
@@ -1415,9 +1447,45 @@ private module MethodResolution {
14151447 or
14161448 traitFunctionResolutionDependsOnArgument0 ( _, _, selfPos , _, f , _, TSelfTypeParameter ( trait ) )
14171449 )
1450+ ) and
1451+ // Exclude functions where we cannot resolve all relevant type mentions; this allows
1452+ // for blanket implementations to be applied in those cases
1453+ forall ( TraitItemNode trait , NonMethodFunction traitFunction , TypeParameter traitTp0 |
1454+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , _, i , f , _, traitTp0 )
1455+ |
1456+ exists ( FunctionPosition pos0 , TypePath path0 |
1457+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos0 , i , f , path0 , traitTp0 ) and
1458+ exists ( getAssocFunctionTypeAt ( f , i , pos0 , path0 ) )
1459+ )
14181460 )
14191461 }
14201462
1463+ pragma [ nomagic]
1464+ private predicate testassocFunctionInfo (
1465+ Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition posAdj ,
1466+ ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType
1467+ ) {
1468+ assocFunctionInfo ( f , name , arity , i , selfPos , selfType ) and
1469+ strippedType = selfType .getTypeAt ( strippedTypePath ) and
1470+ (
1471+ isComplexRootStripped ( strippedTypePath , strippedType )
1472+ or
1473+ selfPos .isTypeQualifier ( ) and strippedTypePath .isEmpty ( )
1474+ ) and
1475+ posAdj = selfPos .getFunctionCallAdjusted ( f ) and
1476+ (
1477+ selfPos .isSelfOrTypeQualifier ( )
1478+ or
1479+ exists ( TraitItemNode trait |
1480+ traitFunctionResolutionDependsOnArgument0 ( _, f , selfPos , _, _, _, TSelfTypeParameter ( trait ) )
1481+ or
1482+ traitFunctionResolutionDependsOnArgument0 ( _, _, selfPos , _, f , _, TSelfTypeParameter ( trait ) )
1483+ )
1484+ ) and
1485+ not assocFunctionInfo ( f , name , arity , selfPos , posAdj , i , selfType , strippedTypePath ,
1486+ strippedType )
1487+ }
1488+
14211489 pragma [ nomagic]
14221490 private predicate assocFunctionInfoTypeParam (
14231491 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition posAdj ,
@@ -1756,6 +1824,24 @@ private module MethodResolution {
17561824 )
17571825 }
17581826
1827+ private predicate foo2 (
1828+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1829+ ) {
1830+ //ImplOrTraitItemNode i
1831+ this = Debug:: getRelevantLocatable ( ) and
1832+ derefChain .isEmpty ( ) and
1833+ strippedType =
1834+ this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1835+ this .hasNoCompatibleTargetCheck ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ,
1836+ getNthLookupType ( strippedType , _) )
1837+ // exists(Type t | t = getNthLookupType(strippedType, n) |
1838+ // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1839+ // strippedTypePath, t)
1840+ // ) and
1841+ // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1842+ // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1843+ }
1844+
17591845 /**
17601846 * Holds if the candidate receiver type represented by `derefChain` does not
17611847 * have a matching method target.
@@ -1768,6 +1854,16 @@ private module MethodResolution {
17681854 )
17691855 }
17701856
1857+ private predicate testhasNoCompatibleTargetNoBorrow (
1858+ FunctionPosition selfPos , DerefChain derefChain
1859+ ) {
1860+ exists ( Type strippedType |
1861+ this .hasNoCompatibleTargetNoBorrowToIndex ( selfPos , derefChain , _, strippedType ,
1862+ getLastLookupTypeIndex ( strippedType ) )
1863+ ) and
1864+ this = Debug:: getRelevantLocatable ( )
1865+ }
1866+
17711867 // forex using recursion
17721868 pragma [ nomagic]
17731869 private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
@@ -1794,6 +1890,29 @@ private module MethodResolution {
17941890 )
17951891 }
17961892
1893+ private predicate sdf (
1894+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType ,
1895+ int n , ImplOrTraitItemNode i
1896+ ) {
1897+ (
1898+ this .supportsAutoDerefAndBorrow ( ) and
1899+ selfPos .isSelf ( )
1900+ or
1901+ // needed for the `hasNoCompatibleTarget` check in
1902+ // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1903+ derefChain .isEmpty ( )
1904+ ) and
1905+ strippedType =
1906+ this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1907+ this = Debug:: getRelevantLocatable ( ) and
1908+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1909+ // this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
1910+ // strippedTypePath, t)
1911+ methodCallNonBlanketCandidate ( this , _, selfPos , _, i , _, strippedTypePath , strippedType ) and
1912+ not this .hasIncompatibleTarget ( i , selfPos , derefChain , TNoBorrowKind ( ) , strippedType )
1913+ )
1914+ }
1915+
17971916 /**
17981917 * Holds if the candidate receiver type represented by `derefChain` does not have
17991918 * a matching non-blanket method target.
@@ -1827,6 +1946,22 @@ private module MethodResolution {
18271946 )
18281947 }
18291948
1949+ private predicate foo (
1950+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1951+ ) {
1952+ //ImplOrTraitItemNode i
1953+ this = Debug:: getRelevantLocatable ( ) and
1954+ this .hasNoCompatibleTargetNoBorrow ( selfPos , derefChain ) and
1955+ strippedType =
1956+ this .getComplexStrippedType ( selfPos , derefChain , TSomeBorrowKind ( false ) , strippedTypePath ) //and
1957+ // exists(Type t | t = getNthLookupType(strippedType, n) |
1958+ // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1959+ // strippedTypePath, t)
1960+ // ) and
1961+ // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1962+ // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1963+ }
1964+
18301965 /**
18311966 * Holds if the candidate receiver type represented by `derefChain`, followed
18321967 * by a shared borrow, does not have a matching method target.
@@ -2194,13 +2329,13 @@ private module MethodResolution {
21942329
21952330 pragma [ nomagic]
21962331 predicate hasNoCompatibleNonBlanketTarget ( ) {
2197- mc_ .hasNoCompatibleNonBlanketTargetSharedBorrow ( selfPos , derefChain ) and
2332+ mc_ .hasNoCompatibleNonBlanketTargetSharedBorrow ( _ , derefChain ) and
21982333 borrow .isSharedBorrow ( )
21992334 or
2200- mc_ .hasNoCompatibleNonBlanketTargetMutBorrow ( selfPos , derefChain ) and
2335+ mc_ .hasNoCompatibleNonBlanketTargetMutBorrow ( _ , derefChain ) and
22012336 borrow .isMutableBorrow ( )
22022337 or
2203- mc_ .hasNoCompatibleNonBlanketTargetNoBorrow ( selfPos , derefChain ) and
2338+ mc_ .hasNoCompatibleNonBlanketTargetNoBorrow ( _ , derefChain ) and
22042339 borrow .isNoBorrow ( )
22052340 }
22062341
@@ -2367,6 +2502,28 @@ private module MethodResolution {
23672502 blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
23682503 )
23692504 }
2505+
2506+ pragma [ nomagic]
2507+ predicate testhasBlanketCandidate (
2508+ MethodCallCand mcc , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
2509+ ) {
2510+ exists ( MethodCall mc , FunctionPosition pos , BorrowKind borrow |
2511+ mcc = MkMethodCallCand ( mc , _, pos , _, borrow ) and
2512+ blanketPath .isEmpty ( ) and
2513+ mc = Debug:: getRelevantLocatable ( ) and
2514+ methodCallBlanketLikeCandidate ( mc , _, _, pos , impl , _, blanketPath , blanketTypeParam ) and
2515+ impl .isBlanketImplementation ( ) and
2516+ // Only apply blanket implementations when no other implementations are possible;
2517+ // this is to account for codebases that use the (unstable) specialization feature
2518+ // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2519+ // cases where our blanket implementation filtering is not precise enough.
2520+ mcc .hasNoCompatibleNonBlanketTarget ( )
2521+ |
2522+ borrow .isNoBorrow ( )
2523+ or
2524+ blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
2525+ )
2526+ }
23702527 }
23712528
23722529 private module ReceiverSatisfiesBlanketLikeConstraint =
@@ -3937,7 +4094,7 @@ private module Debug {
39374094 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
39384095 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
39394096 filepath .matches ( "%/main.rs" ) and
3940- startline = 661
4097+ startline = 570
39414098 )
39424099 }
39434100
0 commit comments