@@ -1331,7 +1331,7 @@ private class BorrowKind extends TBorrowKind {
13311331}
13321332
13331333/**
1334- * Provides logic for resolving calls to methods .
1334+ * Provides logic for resolving calls to associated functions .
13351335 *
13361336 * When resolving a method call, a list of [candidate receiver types][1] is constructed
13371337 *
@@ -1365,67 +1365,30 @@ private class BorrowKind extends TBorrowKind {
13651365 *
13661366 * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
13671367 */
1368- private module MethodResolution {
1369- pragma [ nomagic]
1370- private predicate functionResolutionDependsOnArgument (
1371- ImplItemNode impl , Function f , TypeParameter tp , FunctionPosition pos
1372- ) {
1373- FunctionOverloading:: functionResolutionDependsOnArgument ( impl , f , tp , pos )
1374- // or
1375- // // For inherent implementations of generic types, we also need to check the type being
1376- // // implemented. We arbitrarily choose the first type parameter of the type being implemented
1377- // // to represent this case.
1378- // f = impl.getAnAssocItem() and
1379- // not impl.(Impl).hasTrait() and
1380- // tp = TTypeParamTypeParameter(impl.resolveSelfTy().getTypeParam(0)) and
1381- // pos.isSelf()
1382- }
1383-
1368+ private module AssocFunctionResolution {
1369+ /**
1370+ * Holds if the non-method trait function `f` mentions the implicit `Self` type
1371+ * parameter at `pos`.
1372+ */
13841373 pragma [ nomagic]
1385- private predicate traitFunctionResolutionDependsOnArgument0 (
1386- // todo: copied
1387- TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , ImplItemNode impl ,
1388- NonMethodFunction implFunction , TypePath path , TypeParameter traitTp
1374+ private predicate traitSelfTypeParameterOccurrence (
1375+ TraitItemNode trait , NonMethodFunction f , FunctionPosition pos
13891376 ) {
1390- implFunction = impl .getAnAssocItem ( ) and
1391- implFunction .implements ( traitFunction ) and
1392- FunctionOverloading:: traitTypeParameterOccurrence ( trait , traitFunction , _, pos , path , traitTp ) and
1393- (
1394- traitTp = TSelfTypeParameter ( trait )
1395- or
1396- functionResolutionDependsOnArgument ( impl , implFunction , traitTp , pos )
1397- )
1377+ FunctionOverloading:: traitTypeParameterOccurrence ( trait , f , _, pos , _, TSelfTypeParameter ( trait ) )
13981378 }
13991379
14001380 /**
1401- * Holds if resolving the function `implFunction` in `impl` requires inspecting
1402- * the type of applied _arguments_ or possibly knowing the return type.
1403- *
1404- * `traitTp` is a type parameter of the trait being implemented by `impl`, and
1405- * we need to check that the type of `f` corresponding to `traitTp` is satisfied
1406- * at any one of the positions `pos` in which that type occurs in `f` (at `path`).
1407- *
1408- * As for method resolution, we always check the type being implemented (corresponding
1409- * to `traitTp` being the special `Self` type parameter).
1381+ * Holds if the non-method function `f` implements a trait function that mentions
1382+ * the implicit `Self` type parameter at `pos`.
14101383 */
14111384 pragma [ nomagic]
1412- private predicate traitFunctionResolutionDependsOnArgument (
1413- TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , ImplItemNode impl ,
1414- NonMethodFunction implFunction , TypePath path , TypeParameter traitTp
1385+ private predicate traitImplSelfTypeParameterOccurrence (
1386+ ImplItemNode impl , NonMethodFunction f , FunctionPosition pos
14151387 ) {
1416- traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos , impl , implFunction , path ,
1417- traitTp ) and
1418- // Exclude functions where we cannot resolve all relevant type mentions; this allows
1419- // for blanket implementations to be applied in those cases
1420- forall ( TypeParameter traitTp0 |
1421- traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , _, impl , implFunction , _,
1422- traitTp0 )
1423- |
1424- exists ( FunctionPosition pos0 , TypePath path0 |
1425- traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos0 , impl , implFunction ,
1426- path0 , traitTp0 ) and
1427- exists ( getAssocFunctionTypeAt ( implFunction , impl , pos0 , path0 ) )
1428- )
1388+ exists ( NonMethodFunction traitFunction |
1389+ f = impl .getAnAssocItem ( ) and
1390+ f .implements ( traitFunction ) and
1391+ traitSelfTypeParameterOccurrence ( _, traitFunction , pos )
14291392 )
14301393 }
14311394
@@ -1454,48 +1417,10 @@ private module MethodResolution {
14541417 (
14551418 selfPos .isSelfOrTypeQualifier ( )
14561419 or
1457- exists ( TraitItemNode trait |
1458- traitFunctionResolutionDependsOnArgument0 ( _, f , selfPos , _, _, _, TSelfTypeParameter ( trait ) )
1459- or
1460- traitFunctionResolutionDependsOnArgument0 ( _, _, selfPos , _, f , _, TSelfTypeParameter ( trait ) )
1461- )
1462- ) and
1463- // Exclude functions where we cannot resolve all relevant type mentions; this allows
1464- // for blanket implementations to be applied in those cases
1465- forall ( TraitItemNode trait , NonMethodFunction traitFunction , TypeParameter traitTp0 |
1466- traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , _, i , f , _, traitTp0 )
1467- |
1468- exists ( FunctionPosition pos0 , TypePath path0 |
1469- traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos0 , i , f , path0 , traitTp0 ) and
1470- exists ( getAssocFunctionTypeAt ( f , i , pos0 , path0 ) )
1471- )
1472- )
1473- }
1474-
1475- pragma [ nomagic]
1476- private predicate testassocFunctionInfo (
1477- Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition posAdj ,
1478- ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType
1479- ) {
1480- assocFunctionInfo ( f , name , arity , i , selfPos , selfType ) and
1481- strippedType = selfType .getTypeAt ( strippedTypePath ) and
1482- (
1483- isComplexRootStripped ( strippedTypePath , strippedType )
1484- or
1485- selfPos .isTypeQualifier ( ) and strippedTypePath .isEmpty ( )
1486- ) and
1487- posAdj = selfPos .getFunctionCallAdjusted ( f ) and
1488- (
1489- selfPos .isSelfOrTypeQualifier ( )
1420+ traitSelfTypeParameterOccurrence ( i , f , selfPos )
14901421 or
1491- exists ( TraitItemNode trait |
1492- traitFunctionResolutionDependsOnArgument0 ( _, f , selfPos , _, _, _, TSelfTypeParameter ( trait ) )
1493- or
1494- traitFunctionResolutionDependsOnArgument0 ( _, _, selfPos , _, f , _, TSelfTypeParameter ( trait ) )
1495- )
1496- ) and
1497- not assocFunctionInfo ( f , name , arity , selfPos , posAdj , i , selfType , strippedTypePath ,
1498- strippedType )
1422+ traitImplSelfTypeParameterOccurrence ( i , f , selfPos )
1423+ )
14991424 }
15001425
15011426 pragma [ nomagic]
@@ -1544,9 +1469,7 @@ private module MethodResolution {
15441469 (
15451470 selfPos .isSelfOrTypeQualifier ( )
15461471 or
1547- traitFunctionResolutionDependsOnArgument0 ( _, f , selfPos , _, _, _, TSelfTypeParameter ( trait ) )
1548- or
1549- traitFunctionResolutionDependsOnArgument0 ( _, _, selfPos , _, f , _, TSelfTypeParameter ( trait ) )
1472+ traitImplSelfTypeParameterOccurrence ( impl , f , selfPos )
15501473 )
15511474 }
15521475
@@ -1852,24 +1775,6 @@ private module MethodResolution {
18521775 )
18531776 }
18541777
1855- private predicate foo2 (
1856- FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1857- ) {
1858- //ImplOrTraitItemNode i
1859- this = Debug:: getRelevantLocatable ( ) and
1860- derefChain .isEmpty ( ) and
1861- strippedType =
1862- this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1863- this .hasNoCompatibleTargetCheck ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ,
1864- getNthLookupType ( strippedType , _) )
1865- // exists(Type t | t = getNthLookupType(strippedType, n) |
1866- // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1867- // strippedTypePath, t)
1868- // ) and
1869- // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1870- // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1871- }
1872-
18731778 /**
18741779 * Holds if the candidate receiver type represented by `derefChain` does not
18751780 * have a matching method target.
@@ -1882,16 +1787,6 @@ private module MethodResolution {
18821787 )
18831788 }
18841789
1885- private predicate testhasNoCompatibleTargetNoBorrow (
1886- FunctionPosition selfPos , DerefChain derefChain
1887- ) {
1888- exists ( Type strippedType |
1889- this .hasNoCompatibleTargetNoBorrowToIndex ( selfPos , derefChain , _, strippedType ,
1890- getLastLookupTypeIndex ( strippedType ) )
1891- ) and
1892- this = Debug:: getRelevantLocatable ( )
1893- }
1894-
18951790 // forex using recursion
18961791 pragma [ nomagic]
18971792 private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex (
@@ -1918,29 +1813,6 @@ private module MethodResolution {
19181813 )
19191814 }
19201815
1921- private predicate sdf (
1922- FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType ,
1923- int n , ImplOrTraitItemNode i
1924- ) {
1925- (
1926- this .supportsAutoDerefAndBorrow ( ) and
1927- selfPos .isSelf ( )
1928- or
1929- // needed for the `hasNoCompatibleTarget` check in
1930- // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1931- derefChain .isEmpty ( )
1932- ) and
1933- strippedType =
1934- this .getComplexStrippedType ( selfPos , derefChain , TNoBorrowKind ( ) , strippedTypePath ) and
1935- this = Debug:: getRelevantLocatable ( ) and
1936- exists ( Type t | t = getNthLookupType ( strippedType , n ) |
1937- // this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
1938- // strippedTypePath, t)
1939- methodCallNonBlanketCandidate ( this , _, selfPos , _, i , _, strippedTypePath , strippedType ) and
1940- not this .hasIncompatibleTarget ( i , selfPos , derefChain , TNoBorrowKind ( ) , strippedType )
1941- )
1942- }
1943-
19441816 /**
19451817 * Holds if the candidate receiver type represented by `derefChain` does not have
19461818 * a matching non-blanket method target.
@@ -1974,22 +1846,6 @@ private module MethodResolution {
19741846 )
19751847 }
19761848
1977- private predicate foo (
1978- FunctionPosition selfPos , DerefChain derefChain , TypePath strippedTypePath , Type strippedType
1979- ) {
1980- //ImplOrTraitItemNode i
1981- this = Debug:: getRelevantLocatable ( ) and
1982- this .hasNoCompatibleTargetNoBorrow ( selfPos , derefChain ) and
1983- strippedType =
1984- this .getComplexStrippedType ( selfPos , derefChain , TSomeBorrowKind ( false ) , strippedTypePath ) //and
1985- // exists(Type t | t = getNthLookupType(strippedType, n) |
1986- // this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1987- // strippedTypePath, t)
1988- // ) and
1989- // methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1990- // not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1991- }
1992-
19931849 /**
19941850 * Holds if the candidate receiver type represented by `derefChain`, followed
19951851 * by a shared borrow, does not have a matching method target.
@@ -2425,7 +2281,7 @@ private module MethodResolution {
24252281 pragma [ nomagic]
24262282 Function resolveCallTarget ( ImplOrTraitItemNode i ) {
24272283 result = this .resolveCallTargetCand ( i ) and
2428- not functionResolutionDependsOnArgument ( i , result , _, _)
2284+ not FunctionOverloading :: functionResolutionDependsOnArgument ( i , result , _, _)
24292285 or
24302286 MethodArgsAreInstantiationsOf:: argsAreInstantiationsOf ( mc_ , i , result )
24312287 }
@@ -2526,28 +2382,6 @@ private module MethodResolution {
25262382 blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
25272383 )
25282384 }
2529-
2530- pragma [ nomagic]
2531- predicate testhasBlanketCandidate (
2532- MethodCallCand mcc , ImplItemNode impl , TypePath blanketPath , TypeParam blanketTypeParam
2533- ) {
2534- exists ( MethodCall mc , FunctionPosition pos , BorrowKind borrow |
2535- mcc = MkMethodCallCand ( mc , _, pos , _, borrow ) and
2536- blanketPath .isEmpty ( ) and
2537- mc = Debug:: getRelevantLocatable ( ) and
2538- methodCallBlanketLikeCandidate ( mc , _, _, pos , impl , _, blanketPath , blanketTypeParam ) and
2539- impl .isBlanketImplementation ( ) and
2540- // Only apply blanket implementations when no other implementations are possible;
2541- // this is to account for codebases that use the (unstable) specialization feature
2542- // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2543- // cases where our blanket implementation filtering is not precise enough.
2544- mcc .hasNoCompatibleNonBlanketTarget ( )
2545- |
2546- borrow .isNoBorrow ( )
2547- or
2548- blanketPath .getHead ( ) = borrow .getRefType ( ) .getPositionalTypeParameter ( 0 )
2549- )
2550- }
25512385 }
25522386
25532387 private module ReceiverSatisfiesBlanketLikeConstraint =
@@ -2578,17 +2412,6 @@ private module MethodResolution {
25782412 )
25792413 }
25802414
2581- pragma [ nomagic]
2582- private predicate testpotentialInstantiationOf0 (
2583- MethodCallCand mcc , ImplOrTraitItemNode i , AssocFunctionType selfType , MethodCall mc ,
2584- FunctionPosition selfPos , FunctionPosition pos , Function f , string name , int arity ,
2585- TypePath strippedTypePath , Type strippedType
2586- ) {
2587- mc = Debug:: getRelevantLocatable ( ) and
2588- mcc .hasSignature ( mc , pos , strippedTypePath , strippedType , name , arity ) and
2589- methodCallNonBlanketCandidate ( mc , f , selfPos , pos , i , selfType , strippedTypePath , strippedType )
2590- }
2591-
25922415 pragma [ nomagic]
25932416 predicate potentialInstantiationOf (
25942417 MethodCallCand mcc , TypeAbstraction abs , AssocFunctionType constraint
@@ -2666,7 +2489,7 @@ private module MethodResolution {
26662489 */
26672490 private module MethodArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig {
26682491 predicate toCheck ( ImplOrTraitItemNode i , Function f , TypeParameter traitTp , FunctionPosition pos ) {
2669- functionResolutionDependsOnArgument ( i , f , traitTp , pos )
2492+ FunctionOverloading :: functionResolutionDependsOnArgument ( i , f , traitTp , pos )
26702493 }
26712494
26722495 final private class MethodCallFinal = MethodCall ;
@@ -2751,7 +2574,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
27512574 )
27522575 }
27532576
2754- final private class MethodCallFinal = MethodResolution :: MethodCall ;
2577+ final private class MethodCallFinal = AssocFunctionResolution :: MethodCall ;
27552578
27562579 class Access extends MethodCallFinal , ContextTyping:: ContextTypedCallCand {
27572580 Access ( ) {
@@ -3152,7 +2975,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig {
31522975 exists ( ImplOrTraitItemNodeOption i , NonMethodFunctionDeclaration f |
31532976 result = TNonMethodFunctionDeclaration ( i , f )
31542977 |
3155- f = this .( MethodResolution :: MethodCall ) .resolveCallTarget ( i .asSome ( ) , _, _, _) // mutual recursion; resolving some associated function calls requires resolving types
2978+ f = this .( AssocFunctionResolution :: MethodCall ) .resolveCallTarget ( i .asSome ( ) , _, _, _) // mutual recursion; resolving some associated function calls requires resolving types
31562979 or
31572980 f = this .resolveCallTargetViaPathResolution ( ) and
31582981 f .isDirectlyFor ( i )
@@ -3249,7 +3072,7 @@ private module OperationMatchingInput implements MatchingInputSig {
32493072 }
32503073 }
32513074
3252- class Access extends MethodResolution :: MethodCallOperation {
3075+ class Access extends AssocFunctionResolution :: MethodCallOperation {
32533076 Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) { none ( ) }
32543077
32553078 pragma [ nomagic]
@@ -3970,7 +3793,8 @@ private module Cached {
39703793 cached
39713794 predicate implicitDerefChainBorrow ( Expr e , DerefChain derefChain , boolean borrow ) {
39723795 exists ( BorrowKind bk |
3973- any ( MethodResolution:: MethodCall mc ) .argumentHasImplicitDerefChainBorrow ( e , derefChain , bk ) and
3796+ any ( AssocFunctionResolution:: MethodCall mc )
3797+ .argumentHasImplicitDerefChainBorrow ( e , derefChain , bk ) and
39743798 if bk .isNoBorrow ( ) then borrow = false else borrow = true
39753799 )
39763800 or
@@ -4002,7 +3826,7 @@ private module Cached {
40023826 or
40033827 i instanceof ImplItemNode and dispatch = false
40043828 |
4005- result = call .( MethodResolution :: MethodCall ) .resolveCallTarget ( i , _, _, _)
3829+ result = call .( AssocFunctionResolution :: MethodCall ) .resolveCallTarget ( i , _, _, _)
40063830 )
40073831 }
40083832
0 commit comments