@@ -11,6 +11,7 @@ private import codeql.rust.frameworks.stdlib.Stdlib
11
11
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
12
12
private import codeql.rust.elements.Call
13
13
private import codeql.rust.elements.internal.CallImpl:: Impl as CallImpl
14
+ private import codeql.rust.elements.internal.CallExprImpl:: Impl as CallExprImpl
14
15
15
16
class Type = T:: Type ;
16
17
@@ -724,8 +725,6 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
724
725
}
725
726
}
726
727
727
- private import codeql.rust.elements.internal.CallExprImpl:: Impl as CallExprImpl
728
-
729
728
final class Access extends Call {
730
729
pragma [ nomagic]
731
730
Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
@@ -771,7 +770,9 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
771
770
Declaration getTarget ( ) {
772
771
result = resolveMethodCallTarget ( this ) // mutual recursion; resolving method calls requires resolving types and vice versa
773
772
or
774
- result = CallExprImpl:: getResolvedFunction ( this )
773
+ result = resolveCallTargetSimple ( this )
774
+ or
775
+ result = resolveCallTargetComplex ( this ) // mutual recursion
775
776
}
776
777
}
777
778
@@ -1347,7 +1348,7 @@ private predicate implSiblingCandidate(
1347
1348
// siblings).
1348
1349
not exists ( impl .getAttributeMacroExpansion ( ) ) and
1349
1350
// We use this for resolving methods, so exclude traits that do not have methods.
1350
- exists ( Function f | f = trait .getASuccessor ( _) and f . getParamList ( ) . hasSelfParam ( ) ) and
1351
+ exists ( Function f | f = trait .getASuccessor ( _) ) and
1351
1352
selfTy = impl .getSelfTy ( ) and
1352
1353
rootType = selfTy .resolveType ( )
1353
1354
}
@@ -1496,6 +1497,58 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
1496
1497
result = getMethodSuccessor ( trait .getImplTraitTypeRepr ( ) , name )
1497
1498
}
1498
1499
1500
+ pragma [ nomagic]
1501
+ private predicate assocFuncResolutionDependsOnArgument ( Function f , Impl impl , int pos ) {
1502
+ methodResolutionDependsOnArgument ( impl , _, f , pos , _, _)
1503
+ }
1504
+
1505
+ private class AssocFuncCallExpr extends CallExpr {
1506
+ private int pos ;
1507
+
1508
+ AssocFuncCallExpr ( ) {
1509
+ assocFuncResolutionDependsOnArgument ( CallExprImpl:: getResolvedFunction ( this ) , _, pos )
1510
+ }
1511
+
1512
+ Function getACandidate ( Impl impl ) {
1513
+ result = CallExprImpl:: getResolvedFunction ( this ) and
1514
+ assocFuncResolutionDependsOnArgument ( result , impl , pos )
1515
+ }
1516
+
1517
+ int getPosition ( ) { result = pos }
1518
+
1519
+ /** Gets the type of the receiver of the associated function call at `path`. */
1520
+ Type getTypeAt ( TypePath path ) { result = inferType ( this .getArg ( pos ) , path ) }
1521
+ }
1522
+
1523
+ private module AssocFuncIsInstantiationOfInput implements
1524
+ IsInstantiationOfInputSig< AssocFuncCallExpr >
1525
+ {
1526
+ pragma [ nomagic]
1527
+ predicate potentialInstantiationOf (
1528
+ AssocFuncCallExpr ce , TypeAbstraction impl , TypeMention constraint
1529
+ ) {
1530
+ exists ( Function cand |
1531
+ cand = ce .getACandidate ( impl ) and
1532
+ constraint = cand .getParam ( ce .getPosition ( ) ) .getTypeRepr ( )
1533
+ )
1534
+ }
1535
+ }
1536
+
1537
+ pragma [ nomagic]
1538
+ ItemNode resolveCallTargetSimple ( CallExpr ce ) {
1539
+ result = CallExprImpl:: getResolvedFunction ( ce ) and
1540
+ not assocFuncResolutionDependsOnArgument ( result , _, _)
1541
+ }
1542
+
1543
+ pragma [ nomagic]
1544
+ Function resolveCallTargetComplex ( AssocFuncCallExpr ce ) {
1545
+ exists ( Impl impl |
1546
+ IsInstantiationOf< AssocFuncCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( ce ,
1547
+ impl , _) and
1548
+ result = getMethodSuccessor ( impl , ce .getACandidate ( _) .getName ( ) .getText ( ) )
1549
+ )
1550
+ }
1551
+
1499
1552
cached
1500
1553
private module Cached {
1501
1554
private import codeql.rust.internal.CachedStages
@@ -1538,6 +1591,14 @@ private module Cached {
1538
1591
result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1539
1592
}
1540
1593
1594
+ /** Gets a method that the method call `mc` resolves to, if any. */
1595
+ cached
1596
+ Function resolveCallTarget ( CallExpr ce ) {
1597
+ result = resolveCallTargetSimple ( ce )
1598
+ or
1599
+ result = resolveCallTargetComplex ( ce )
1600
+ }
1601
+
1541
1602
pragma [ inline]
1542
1603
private Type inferRootTypeDeref ( AstNode n ) {
1543
1604
result = inferType ( n ) and
@@ -1682,9 +1743,9 @@ private module Debug {
1682
1743
result = inferType ( n , path )
1683
1744
}
1684
1745
1685
- Function debugResolveMethodCallTarget ( Call mce ) {
1686
- mce = getRelevantLocatable ( ) and
1687
- result = resolveMethodCallTarget ( mce )
1746
+ Function debugResolveCallTarget ( Call c ) {
1747
+ c = getRelevantLocatable ( ) and
1748
+ result = [ resolveMethodCallTarget ( c ) , resolveCallTarget ( c ) ]
1688
1749
}
1689
1750
1690
1751
predicate debugInferImplicitSelfType ( SelfParam self , TypePath path , Type t ) {
@@ -1702,6 +1763,11 @@ private module Debug {
1702
1763
tm .resolveTypeAt ( path ) = type
1703
1764
}
1704
1765
1766
+ Type debugInferAnnotatedType ( AstNode n , TypePath path ) {
1767
+ n = getRelevantLocatable ( ) and
1768
+ result = inferAnnotatedType ( n , path )
1769
+ }
1770
+
1705
1771
pragma [ nomagic]
1706
1772
private int countTypesAtPath ( AstNode n , TypePath path , Type t ) {
1707
1773
t = inferType ( n , path ) and
0 commit comments