@@ -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 ,
@@ -1648,6 +1716,13 @@ private module MethodResolution {
16481716 _, derefChain , borrow ) , i , _, path ) and
16491717 path .isCons ( root .getATypeParameter ( ) , _)
16501718 )
1719+ or
1720+ exists ( AssocFunctionType selfType |
1721+ ReceiverIsInstantiationOfSelfParam:: argIsInstantiationOf ( MkMethodCallCand ( this , selfPos , _,
1722+ derefChain , borrow ) , i , selfType ) and
1723+ MethodArgsAreInstantiationsOf:: argsAreNotInstantiationsOf ( this , i , _) and
1724+ root = selfType .getTypeAt ( TypePath:: nil ( ) )
1725+ )
16511726 }
16521727
16531728 /**
@@ -1756,6 +1831,24 @@ private module MethodResolution {
17561831 )
17571832 }
17581833
1834+ private predicate foo2 (
1835+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1836+ ) {
1837+ //ImplOrTraitItemNode i
1838+ this = Debug:: getRelevantLocatable ( ) and
1839+ derefChain .isEmpty ( ) and
1840+ strippedType =
1841+ this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1842+ this .hasNoCompatibleTargetCheck ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ,
1843+ getNthLookupType ( strippedType , _) )
1844+ // exists(Type t | t = getNthLookupType(strippedType, n) |
1845+ // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1846+ // strippedTypePath, t)
1847+ // ) and
1848+ // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1849+ // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1850+ }
1851+
17591852 /**
17601853 * Holds if the candidate receiver type represented by `derefChain` does not
17611854 * have a matching method target.
@@ -1768,6 +1861,16 @@ private module MethodResolution {
17681861 )
17691862 }
17701863
1864+ private predicate testhasNoCompatibleTargetNoBorrow (
1865+ FunctionPosition selfPos , DerefChain derefChain
1866+ ) {
1867+ exists ( Type strippedType |
1868+ this .hasNoCompatibleTargetNoBorrowToIndex ( selfPos , derefChain , _, strippedType ,
1869+ getLastLookupTypeIndex ( strippedType ) )
1870+ ) and
1871+ this = Debug:: getRelevantLocatable ( )
1872+ }
1873+
17711874 // forex using recursion
17721875 pragma [ nomagic]
17731876 private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
@@ -1794,6 +1897,29 @@ private module MethodResolution {
17941897 )
17951898 }
17961899
1900+ private predicate sdf (
1901+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType ,
1902+ int n , ImplOrTraitItemNode i
1903+ ) {
1904+ (
1905+ this .supportsAutoDerefAndBorrow ( ) and
1906+ selfPos .isSelf ( )
1907+ or
1908+ // needed for the `hasNoCompatibleTarget` check in
1909+ // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1910+ derefChain .isEmpty ( )
1911+ ) and
1912+ strippedType =
1913+ this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1914+ this = Debug:: getRelevantLocatable ( ) and
1915+ exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1916+ // this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
1917+ // strippedTypePath, t)
1918+ methodCallNonBlanketCandidate ( this , _, selfPos , _, i , _, strippedTypePath , strippedType ) and
1919+ not this .hasIncompatibleTarget ( i , selfPos , derefChain , TNoBorrowKind ( ) , strippedType )
1920+ )
1921+ }
1922+
17971923 /**
17981924 * Holds if the candidate receiver type represented by `derefChain` does not have
17991925 * a matching non-blanket method target.
@@ -1827,6 +1953,22 @@ private module MethodResolution {
18271953 )
18281954 }
18291955
1956+ private predicate foo (
1957+ FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1958+ ) {
1959+ //ImplOrTraitItemNode i
1960+ this = Debug:: getRelevantLocatable ( ) and
1961+ this .hasNoCompatibleTargetNoBorrow ( selfPos , derefChain ) and
1962+ strippedType =
1963+ this .getComplexStrippedType ( selfPos , derefChain , TSomeBorrowKind ( false ) , strippedTypePath ) //and
1964+ // exists(Type t | t = getNthLookupType(strippedType, n) |
1965+ // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1966+ // strippedTypePath, t)
1967+ // ) and
1968+ // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1969+ // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1970+ }
1971+
18301972 /**
18311973 * Holds if the candidate receiver type represented by `derefChain`, followed
18321974 * by a shared borrow, does not have a matching method target.
@@ -2367,6 +2509,28 @@ private module MethodResolution {
23672509 blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
23682510 )
23692511 }
2512+
2513+ pragma [ nomagic]
2514+ predicate testhasBlanketCandidate (
2515+ MethodCallCand mcc , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
2516+ ) {
2517+ exists ( MethodCall mc , FunctionPosition pos , BorrowKind borrow |
2518+ mcc = MkMethodCallCand ( mc , _, pos , _, borrow ) and
2519+ blanketPath .isEmpty ( ) and
2520+ mc = Debug:: getRelevantLocatable ( ) and
2521+ methodCallBlanketLikeCandidate ( mc , _, _, pos , impl , _, blanketPath , blanketTypeParam ) and
2522+ impl .isBlanketImplementation ( ) and
2523+ // Only apply blanket implementations when no other implementations are possible;
2524+ // this is to account for codebases that use the (unstable) specialization feature
2525+ // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2526+ // cases where our blanket implementation filtering is not precise enough.
2527+ mcc .hasNoCompatibleNonBlanketTarget ( )
2528+ |
2529+ borrow .isNoBorrow ( )
2530+ or
2531+ blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
2532+ )
2533+ }
23702534 }
23712535
23722536 private module ReceiverSatisfiesBlanketLikeConstraint =
@@ -2397,6 +2561,22 @@ private module MethodResolution {
23972561 )
23982562 }
23992563
2564+ pragma [ nomagic]
2565+ private predicate testpotentialInstantiationOf0 (
2566+ MethodCallCand mcc , ImplOrTraitItemNode i , AssocFunctionType selfType , MethodCall mc ,
2567+ FunctionPosition pos , Function f , string name , int arity , TypePath strippedTypePath ,
2568+ Type strippedType
2569+ ) {
2570+ mc = Debug:: getRelevantLocatable ( ) and
2571+ mcc .hasSignature ( mc , pos , strippedTypePath , strippedType , name , arity ) and
2572+ (
2573+ methodCallNonBlanketCandidate ( mc , f , _, pos , i , selfType , strippedTypePath , strippedType )
2574+ or
2575+ methodCallBlanketLikeCandidate ( mc , f , _, pos , i , selfType , _, _) and
2576+ ReceiverSatisfiesBlanketLikeConstraint:: satisfiesBlanketConstraint ( mcc , i )
2577+ )
2578+ }
2579+
24002580 pragma [ nomagic]
24012581 predicate potentialInstantiationOf (
24022582 MethodCallCand mcc , TypeAbstraction abs , AssocFunctionType constraint
@@ -3936,8 +4116,8 @@ private module Debug {
39364116 Locatable getRelevantLocatable ( ) {
39374117 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
39384118 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
3939- filepath .matches ( "%/main .rs" ) and
3940- startline = 661
4119+ filepath .matches ( "%/overloading .rs" ) and
4120+ startline = 399
39414121 )
39424122 }
39434123
0 commit comments