@@ -11,6 +11,7 @@ private import codeql.rust.frameworks.stdlib.Stdlib
1111private import codeql.rust.frameworks.stdlib.Builtins as Builtins
1212private import codeql.rust.elements.Call
1313private import codeql.rust.elements.internal.CallImpl:: Impl as CallImpl
14+ private import codeql.rust.elements.internal.CallExprImpl:: Impl as CallExprImpl
1415
1516class Type = T:: Type ;
1617
@@ -699,8 +700,6 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
699700 }
700701 }
701702
702- private import codeql.rust.elements.internal.CallExprImpl:: Impl as CallExprImpl
703-
704703 final class Access extends Call {
705704 pragma [ nomagic]
706705 Type getTypeArgument ( TypeArgumentPosition apos , TypePath path ) {
@@ -746,7 +745,9 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
746745 Declaration getTarget ( ) {
747746 result = resolveMethodCallTarget ( this ) // mutual recursion; resolving method calls requires resolving types and vice versa
748747 or
749- result = CallExprImpl:: getResolvedFunction ( this )
748+ result = resolveCallTargetSimple ( this )
749+ or
750+ result = resolveCallTargetComplex ( this ) // mutual recursion
750751 }
751752 }
752753
@@ -1290,7 +1291,7 @@ private predicate implSiblingCandidate(
12901291 // siblings).
12911292 not exists ( impl .getAttributeMacroExpansion ( ) ) and
12921293 // We use this for resolving methods, so exclude traits that do not have methods.
1293- exists ( Function f | f = trait .getASuccessor ( _) and f . getParamList ( ) . hasSelfParam ( ) ) and
1294+ exists ( Function f | f = trait .getASuccessor ( _) ) and
12941295 selfTy = impl .getSelfTy ( ) and
12951296 rootType = selfTy .resolveType ( )
12961297}
@@ -1439,6 +1440,58 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
14391440 result = getMethodSuccessor ( trait .getImplTraitTypeRepr ( ) , name )
14401441}
14411442
1443+ pragma [ nomagic]
1444+ private predicate assocFuncResolutionDependsOnArgument ( Function f , Impl impl , int pos ) {
1445+ methodResolutionDependsOnArgument ( impl , _, f , pos , _, _)
1446+ }
1447+
1448+ private class AssocFuncCallExpr extends CallExpr {
1449+ private int pos ;
1450+
1451+ AssocFuncCallExpr ( ) {
1452+ assocFuncResolutionDependsOnArgument ( CallExprImpl:: getResolvedFunction ( this ) , _, pos )
1453+ }
1454+
1455+ Function getACandidate ( Impl impl ) {
1456+ result = CallExprImpl:: getResolvedFunction ( this ) and
1457+ assocFuncResolutionDependsOnArgument ( result , impl , pos )
1458+ }
1459+
1460+ int getPosition ( ) { result = pos }
1461+
1462+ /** Gets the type of the receiver of the associated function call at `path`. */
1463+ Type getTypeAt ( TypePath path ) { result = inferType ( this .getArg ( pos ) , path ) }
1464+ }
1465+
1466+ private module AssocFuncIsInstantiationOfInput implements
1467+ IsInstantiationOfInputSig< AssocFuncCallExpr >
1468+ {
1469+ pragma [ nomagic]
1470+ predicate potentialInstantiationOf (
1471+ AssocFuncCallExpr ce , TypeAbstraction impl , TypeMention constraint
1472+ ) {
1473+ exists ( Function cand |
1474+ cand = ce .getACandidate ( impl ) and
1475+ constraint = cand .getParam ( ce .getPosition ( ) ) .getTypeRepr ( )
1476+ )
1477+ }
1478+ }
1479+
1480+ pragma [ nomagic]
1481+ ItemNode resolveCallTargetSimple ( CallExpr ce ) {
1482+ result = CallExprImpl:: getResolvedFunction ( ce ) and
1483+ not assocFuncResolutionDependsOnArgument ( result , _, _)
1484+ }
1485+
1486+ pragma [ nomagic]
1487+ Function resolveCallTargetComplex ( AssocFuncCallExpr ce ) {
1488+ exists ( Impl impl |
1489+ IsInstantiationOf< AssocFuncCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( ce ,
1490+ impl , _) and
1491+ result = getMethodSuccessor ( impl , ce .getACandidate ( _) .getName ( ) .getText ( ) )
1492+ )
1493+ }
1494+
14421495cached
14431496private module Cached {
14441497 private import codeql.rust.internal.CachedStages
@@ -1481,6 +1534,14 @@ private module Cached {
14811534 result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
14821535 }
14831536
1537+ /** Gets a method that the method call `mc` resolves to, if any. */
1538+ cached
1539+ Function resolveCallTarget ( CallExpr ce ) {
1540+ result = resolveCallTargetSimple ( ce )
1541+ or
1542+ result = resolveCallTargetComplex ( ce )
1543+ }
1544+
14841545 pragma [ inline]
14851546 private Type inferRootTypeDeref ( AstNode n ) {
14861547 result = inferType ( n ) and
0 commit comments