@@ -1392,6 +1392,10 @@ private module AssocFunctionResolution {
13921392 )
13931393 }
13941394
1395+ private module TypeOption = Option< Type > ;
1396+
1397+ private class TypeOption = TypeOption:: Option ;
1398+
13951399 /**
13961400 * Holds if function `f` with the name `name` and the arity `arity` exists in
13971401 * `i`, and the type at `selfPos` is `selfType`.
@@ -1402,12 +1406,16 @@ private module AssocFunctionResolution {
14021406 * and `strippedType` is the type inside the reference.
14031407 *
14041408 * `selfPosAdj` is the function-call adjusted version of `selfPos`.
1409+ *
1410+ * `implType` is the type being implemented (`None` when `i` is a trait).
1411+ *
1412+ * `isMethod` indicates whether `f` is a method.
14051413 */
14061414 pragma [ nomagic]
14071415 private predicate assocFunctionInfo (
14081416 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
14091417 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
1410- TypeOption implType , boolean isMethod
1418+ TypeOption implType , TypeOption trait , boolean isMethod
14111419 ) {
14121420 assocFunctionInfo ( f , name , arity , i , selfPos , selfType ) and
14131421 strippedType = selfType .getTypeAt ( strippedTypePath ) and
@@ -1425,10 +1433,19 @@ private module AssocFunctionResolution {
14251433 traitImplSelfTypeParameterOccurrence ( i , f , selfPos )
14261434 ) and
14271435 (
1428- not i instanceof Impl and
1436+ implType .asSome ( ) = resolveImplSelfTypeAt ( i , TypePath:: nil ( ) )
1437+ or
1438+ i instanceof Trait and
14291439 implType .isNone ( )
1440+ ) and
1441+ (
1442+ trait .asSome ( ) =
1443+ [
1444+ TTrait ( i ) .( Type ) ,
1445+ TTrait ( i .( ImplItemNode ) .resolveTraitTy ( ) ) .( Type )
1446+ ]
14301447 or
1431- implType . asSome ( ) = resolveImplSelfTypeAt ( i , TypePath :: nil ( ) )
1448+ i . ( Impl ) . isInherent ( ) and trait . isNone ( )
14321449 ) and
14331450 if f instanceof Method then isMethod = true else isMethod = false
14341451 }
@@ -1437,21 +1454,21 @@ private module AssocFunctionResolution {
14371454 private predicate assocFunctionInfoNonBlanketLike0 (
14381455 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
14391456 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
1440- TypeOption implType , boolean isMethod
1457+ TypeOption implType , TypeOption trait , boolean isMethod
14411458 ) {
14421459 assocFunctionInfo ( f , name , arity , selfPos , selfPosAdj , i , selfType , strippedTypePath ,
1443- strippedType , implType , isMethod ) and
1460+ strippedType , implType , trait , isMethod ) and
14441461 not BlanketImplementation:: isBlanketLike ( i , _, _)
14451462 }
14461463
14471464 pragma [ nomagic]
14481465 private predicate assocFunctionInfoNonBlanketLikeTypeParam (
14491466 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
14501467 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , TypeParam tp ,
1451- TypeOption implType , boolean isMethod
1468+ TypeOption implType , TypeOption trait , boolean isMethod
14521469 ) {
14531470 assocFunctionInfo ( f , name , arity , selfPos , selfPosAdj , i , selfType , strippedTypePath ,
1454- TTypeParamTypeParameter ( tp ) , implType , isMethod ) and
1471+ TTypeParamTypeParameter ( tp ) , implType , trait , isMethod ) and
14551472 not BlanketImplementation:: isBlanketLike ( i , _, _)
14561473 }
14571474
@@ -1464,12 +1481,12 @@ private module AssocFunctionResolution {
14641481 private predicate assocFunctionInfoNonBlanketLike (
14651482 Function f , string name , int arity , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
14661483 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType ,
1467- TypeOption implType , boolean isMethod
1484+ TypeOption implType , TypeOption trait , boolean isMethod
14681485 ) {
14691486 assocFunctionInfoNonBlanketLike0 ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1470- strippedTypePath , strippedType , implType , isMethod ) or
1487+ strippedTypePath , strippedType , implType , trait , isMethod ) or
14711488 assocFunctionInfoNonBlanketLikeTypeParam ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1472- strippedTypePath , _, implType , isMethod )
1489+ strippedTypePath , _, implType , trait , isMethod )
14731490 }
14741491
14751492 /**
@@ -1500,33 +1517,58 @@ private module AssocFunctionResolution {
15001517 pragma [ nomagic]
15011518 private predicate assocFunctionTraitInfo ( string name , int arity , Trait trait ) {
15021519 exists ( ImplItemNode i |
1503- assocFunctionInfo ( _, name , arity , _, _, i , _, _, _, _, _) and
1520+ assocFunctionInfo ( _, name , arity , _, _, i , _, _, _, _, _, _ ) and
15041521 trait = i .resolveTraitTy ( )
15051522 )
15061523 or
1507- assocFunctionInfo ( _, name , arity , _, _, trait , _, _, _, _, _)
1524+ assocFunctionInfo ( _, name , arity , _, _, trait , _, _, _, _, _, _ )
15081525 }
15091526
15101527 pragma [ nomagic]
15111528 private predicate assocFunctionCallTraitCandidate ( Element afc , Trait trait ) {
15121529 afc =
15131530 any ( AssocFunctionCall afc0 |
15141531 exists ( string name , int arity |
1515- afc0 .hasNameAndArity ( name , arity , _ , _ ) and
1532+ afc0 .hasNameAndArity ( name , arity ) and
15161533 assocFunctionTraitInfo ( name , arity , trait ) and
1517- not afc0 .hasTrait ( )
1534+ not afc0 .hasATrait ( )
15181535 )
15191536 )
15201537 }
15211538
15221539 private module AssocFunctionTraitIsVisible = TraitIsVisible< assocFunctionCallTraitCandidate / 2 > ;
15231540
1524- predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible:: traitIsVisible / 2 ;
1525-
1541+ // private predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2;
15261542 bindingset [ afc, impl]
15271543 pragma [ inline_late]
15281544 private predicate callVisibleImplTraitCandidate ( AssocFunctionCall afc , ImplItemNode impl ) {
1529- callVisibleTraitCandidate ( afc , impl .resolveTraitTy ( ) )
1545+ AssocFunctionTraitIsVisible:: traitIsVisible ( afc , impl .resolveTraitTy ( ) )
1546+ }
1547+
1548+ private Type getNonTypeParameterTypeQualifier ( AssocFunctionCall afc ) {
1549+ result = getCallExprTypeQualifier ( afc , TypePath:: nil ( ) , _) and
1550+ not result instanceof TypeParameter
1551+ }
1552+
1553+ pragma [ nomagic]
1554+ private predicate callInfo (
1555+ AssocFunctionCall afc , string name , int arity , TypeOption typeQualifier ,
1556+ TypeOption traitQualifier , boolean hasReceiver
1557+ ) {
1558+ afc .hasNameAndArity ( name , arity ) and
1559+ ( if afc .hasReceiver ( ) then hasReceiver = true else hasReceiver = false ) and
1560+ (
1561+ typeQualifier .asSome ( ) = getNonTypeParameterTypeQualifier ( afc )
1562+ or
1563+ not exists ( getNonTypeParameterTypeQualifier ( afc ) ) and
1564+ typeQualifier .isNone ( )
1565+ ) and
1566+ (
1567+ traitQualifier .asSome ( ) = TTrait ( afc .getATrait ( ) )
1568+ or
1569+ not afc .hasATrait ( ) and
1570+ traitQualifier .isNone ( )
1571+ )
15301572 }
15311573
15321574 /**
@@ -1546,23 +1588,15 @@ private module AssocFunctionResolution {
15461588 AssocFunctionCall afc , Function f , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
15471589 ImplOrTraitItemNode i , AssocFunctionType selfType , TypePath strippedTypePath , Type strippedType
15481590 ) {
1549- exists ( string name , int arity , TypeOption implType , boolean isMethod |
1550- afc .hasNameAndArity ( name , arity , [ implType , any ( TypeOption non | non .isNone ( ) ) ] , isMethod ) and
1591+ exists ( string name , int arity , TypeOption implType , TypeOption trait , boolean isMethod |
1592+ callInfo ( afc , name , arity , [ implType , any ( TypeOption non | non .isNone ( ) ) ] ,
1593+ [ trait , any ( TypeOption non | non .isNone ( ) ) ] , [ false , isMethod ] ) and
15511594 assocFunctionInfoNonBlanketLike ( f , name , arity , selfPos , selfPosAdj , i , selfType ,
1552- strippedTypePath , strippedType , implType , isMethod )
1595+ strippedTypePath , strippedType , implType , trait , isMethod )
15531596 |
1554- i .( Impl ) .isInherent ( ) and
1555- not afc .hasTrait ( )
1556- or
1557- callVisibleImplTraitCandidate ( afc , i )
1558- or
1559- callVisibleTraitCandidate ( afc , i )
1560- or
1561- exists ( Trait trait | trait = afc .getTrait ( ) |
1562- i .( ImplItemNode ) .resolveTraitTy ( ) = trait
1563- or
1564- i = trait
1565- )
1597+ if not afc .hasATrait ( ) and i .( Impl ) .hasTrait ( )
1598+ then callVisibleImplTraitCandidate ( afc , i )
1599+ else any ( )
15661600 )
15671601 }
15681602
@@ -1583,21 +1617,16 @@ private module AssocFunctionResolution {
15831617 AssocFunctionCall afc , Function f , FunctionPosition selfPos , FunctionPosition selfPosAdj ,
15841618 ImplItemNode impl , AssocFunctionType self , TypePath blanketPath , TypeParam blanketTypeParam
15851619 ) {
1586- exists ( string name , int arity , boolean isMethod |
1587- afc .hasNameAndArity ( name , arity , _, isMethod ) and
1588- assocFunctionSelfInfoBlanketLike ( f , name , arity , selfPos , selfPosAdj , impl , _, self ,
1620+ exists ( string name , int arity , Trait trait , boolean isMethod |
1621+ callInfo ( afc , name , arity , _,
1622+ [ TypeOption:: some ( TTrait ( trait ) ) , any ( TypeOption non | non .isNone ( ) ) ] , [ false , isMethod ] ) and
1623+ assocFunctionSelfInfoBlanketLike ( f , name , arity , selfPos , selfPosAdj , impl , trait , self ,
15891624 blanketPath , blanketTypeParam , isMethod )
15901625 |
1591- callVisibleImplTraitCandidate ( afc , impl )
1592- or
1593- impl .resolveTraitTy ( ) = afc .getTrait ( )
1626+ if not afc .hasATrait ( ) then callVisibleImplTraitCandidate ( afc , impl ) else any ( )
15941627 )
15951628 }
15961629
1597- private module TypeOption = Option< Type > ;
1598-
1599- private class TypeOption = TypeOption:: Option ;
1600-
16011630 /**
16021631 * A (potential) call to an associated function.
16031632 *
@@ -1619,7 +1648,7 @@ private module AssocFunctionResolution {
16191648 * [1]: https://doc.rust-lang.org/std/ops/trait.Index.html
16201649 */
16211650 abstract class AssocFunctionCall extends Expr {
1622- abstract predicate hasNameAndArity ( string name , int arity , TypeOption implType , boolean isMethod ) ;
1651+ abstract predicate hasNameAndArity ( string name , int arity ) ;
16231652
16241653 abstract Expr getNonReturnNodeAt ( FunctionPosition apos ) ;
16251654
@@ -1639,6 +1668,14 @@ private module AssocFunctionResolution {
16391668 /** Holds if this call targets a trait. */
16401669 predicate hasTrait ( ) { exists ( this .getTrait ( ) ) }
16411670
1671+ Trait getATrait ( ) {
1672+ result = this .getTrait ( )
1673+ or
1674+ result = getALookupTrait ( getCallExprTypeQualifier ( this , TypePath:: nil ( ) , _) )
1675+ }
1676+
1677+ predicate hasATrait ( ) { exists ( this .getATrait ( ) ) }
1678+
16421679 Type getTypeAt ( FunctionPosition pos , TypePath path ) {
16431680 result = inferType ( this .getNodeAt ( pos ) , path )
16441681 }
@@ -2077,11 +2114,9 @@ private module AssocFunctionResolution {
20772114
20782115 private class AssocFunctionCallMethodCallExpr extends AssocFunctionCall instanceof MethodCallExpr {
20792116 pragma [ nomagic]
2080- override predicate hasNameAndArity ( string name , int arity , TypeOption implType , boolean isMethod ) {
2117+ override predicate hasNameAndArity ( string name , int arity ) {
20812118 name = super .getIdentifier ( ) .getText ( ) and
2082- arity = super .getArgList ( ) .getNumberOfArgs ( ) + 1 and
2083- implType .isNone ( ) and
2084- isMethod = true
2119+ arity = super .getArgList ( ) .getNumberOfArgs ( ) + 1
20852120 }
20862121
20872122 override Expr getNonReturnNodeAt ( FunctionPosition pos ) {
@@ -2100,11 +2135,9 @@ private module AssocFunctionResolution {
21002135 }
21012136
21022137 pragma [ nomagic]
2103- override predicate hasNameAndArity ( string name , int arity , TypeOption implType , boolean isMethod ) {
2138+ override predicate hasNameAndArity ( string name , int arity ) {
21042139 ( if this .isInMutableContext ( ) then name = "index_mut" else name = "index" ) and
2105- arity = 2 and
2106- implType .isNone ( ) and
2107- isMethod = true
2140+ arity = 2
21082141 }
21092142
21102143 override Expr getNonReturnNodeAt ( FunctionPosition pos ) {
@@ -2133,22 +2166,9 @@ private module AssocFunctionResolution {
21332166 }
21342167
21352168 pragma [ nomagic]
2136- private Type getNonTypeParameterTypeQualifier ( ) {
2137- result = getCallExprTypeQualifier ( this , TypePath:: nil ( ) , _) and
2138- not result instanceof TypeParameter
2139- }
2140-
2141- pragma [ nomagic]
2142- override predicate hasNameAndArity ( string name , int arity , TypeOption implType , boolean isMethod ) {
2169+ override predicate hasNameAndArity ( string name , int arity ) {
21432170 name = CallExprImpl:: getFunctionPath ( this ) .getText ( ) and
2144- arity = super .getArgList ( ) .getNumberOfArgs ( ) and
2145- (
2146- not exists ( this .getNonTypeParameterTypeQualifier ( ) ) and
2147- implType .isNone ( )
2148- or
2149- implType .asSome ( ) = this .getNonTypeParameterTypeQualifier ( )
2150- ) and
2151- isMethod = [ false , true ]
2171+ arity = super .getArgList ( ) .getNumberOfArgs ( )
21522172 }
21532173
21542174 override Expr getNonReturnNodeAt ( FunctionPosition pos ) {
@@ -2169,11 +2189,9 @@ private module AssocFunctionResolution {
21692189
21702190 final class AssocFunctionCallOperation extends AssocFunctionCall instanceof Operation {
21712191 pragma [ nomagic]
2172- override predicate hasNameAndArity ( string name , int arity , TypeOption implType , boolean isMethod ) {
2192+ override predicate hasNameAndArity ( string name , int arity ) {
21732193 super .isOverloaded ( _, name , _) and
2174- arity = super .getNumberOfOperands ( ) and
2175- implType .isNone ( ) and
2176- isMethod = true
2194+ arity = super .getNumberOfOperands ( )
21772195 }
21782196
21792197 override Expr getNonReturnNodeAt ( FunctionPosition pos ) {
@@ -2289,7 +2307,7 @@ private module AssocFunctionResolution {
22892307 selfPos .isTypeQualifier ( ) and strippedTypePath .isEmpty ( )
22902308 ) and
22912309 afc = afc_ and
2292- afc .hasNameAndArity ( name , arity , _ , _ ) and
2310+ afc .hasNameAndArity ( name , arity ) and
22932311 pos = selfPosAdj
22942312 }
22952313
@@ -2316,7 +2334,7 @@ private module AssocFunctionResolution {
23162334 this .hasSignature ( _, selfPosAdj , strippedTypePath , strippedType , name , arity ) and
23172335 forall ( Impl i |
23182336 assocFunctionInfoNonBlanketLike ( _, name , arity , _, selfPosAdj , i , _, strippedTypePath ,
2319- strippedType , _, _) and
2337+ strippedType , _, _, _ ) and
23202338 i .isInherent ( )
23212339 |
23222340 this .hasIncompatibleInherentTarget ( i )
@@ -2327,7 +2345,7 @@ private module AssocFunctionResolution {
23272345 pragma [ nomagic]
23282346 private predicate argIsInstantiationOf ( ImplOrTraitItemNode i , string name , int arity ) {
23292347 ArgIsInstantiationOfSelfParam:: argIsInstantiationOf ( this , i , _) and
2330- afc_ .hasNameAndArity ( name , arity , _ , _ )
2348+ afc_ .hasNameAndArity ( name , arity )
23312349 }
23322350
23332351 pragma [ nomagic]
@@ -2487,7 +2505,7 @@ private module AssocFunctionResolution {
24872505 }
24882506
24892507 predicate relevantConstraint ( AssocFunctionType constraint ) {
2490- assocFunctionInfo ( _, _, _, _, _, _, constraint , _, _, _, _)
2508+ assocFunctionInfo ( _, _, _, _, _, _, constraint , _, _, _, _, _ )
24912509 }
24922510 }
24932511
@@ -4007,8 +4025,8 @@ private module Debug {
40074025 Locatable getRelevantLocatable ( ) {
40084026 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
40094027 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
4010- filepath .matches ( "%/main .rs" ) and
4011- startline = 50
4028+ filepath .matches ( "%/overloading .rs" ) and
4029+ startline = 57
40124030 )
40134031 }
40144032
0 commit comments