@@ -770,9 +770,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
770770 Declaration getTarget ( ) {
771771 result = resolveMethodCallTarget ( this ) // mutual recursion; resolving method calls requires resolving types and vice versa
772772 or
773- result = resolveCallTargetSimple ( this )
774- or
775- result = resolveCallTargetComplex ( this ) // mutual recursion
773+ result = resolveFunctionCallTarget ( this ) // potential mutual recursion; resolving some associated function calls requires resolving types
776774 }
777775 }
778776
@@ -1224,12 +1222,22 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
12241222final class MethodCall extends Call {
12251223 MethodCall ( ) { exists ( this .getReceiver ( ) ) }
12261224
1225+ private Type getReceiverTypeAt ( TypePath path ) {
1226+ result = inferType ( super .getReceiver ( ) , path )
1227+ or
1228+ exists ( PathExpr pe , TypeMention tm |
1229+ pe = this .( CallExpr ) .getFunction ( ) and
1230+ tm = pe .getPath ( ) .getQualifier ( ) and
1231+ result = tm .resolveTypeAt ( path )
1232+ )
1233+ }
1234+
12271235 /** Gets the type of the receiver of the method call at `path`. */
12281236 Type getTypeAt ( TypePath path ) {
12291237 if this .receiverImplicitlyBorrowed ( )
12301238 then
12311239 exists ( TypePath path0 , Type t0 |
1232- t0 = inferType ( super . getReceiver ( ) , path0 ) and
1240+ t0 = this . getReceiverTypeAt ( path0 ) and
12331241 (
12341242 path0 .isCons ( TRefTypeParameter ( ) , path )
12351243 or
@@ -1257,10 +1265,14 @@ final class MethodCall extends Call {
12571265 t0 .( StructType ) .asItemNode ( ) instanceof StringStruct and
12581266 result .( StructType ) .asItemNode ( ) instanceof Builtins:: Str
12591267 )
1260- else result = inferType ( super . getReceiver ( ) , path )
1268+ else result = this . getReceiverTypeAt ( path )
12611269 }
12621270}
12631271
1272+ final private class FunctionCallExpr extends CallExpr {
1273+ FunctionCallExpr ( ) { not this instanceof MethodCall }
1274+ }
1275+
12641276/**
12651277 * Holds if a method for `type` with the name `name` and the arity `arity`
12661278 * exists in `impl`.
@@ -1500,15 +1512,28 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
15001512 result = getMethodSuccessor ( trait .getImplTraitTypeRepr ( ) , name )
15011513}
15021514
1515+ pragma [ nomagic]
1516+ private Function resolveMethodCallTarget ( MethodCall mc ) {
1517+ // The method comes from an `impl` block targeting the type of the receiver.
1518+ result = getMethodFromImpl ( mc )
1519+ or
1520+ // The type of the receiver is a type parameter and the method comes from a
1521+ // trait bound on the type parameter.
1522+ result = getTypeParameterMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1523+ or
1524+ // The type of the receiver is an `impl Trait` type.
1525+ result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1526+ }
1527+
15031528pragma [ nomagic]
15041529private predicate assocFuncResolutionDependsOnArgument ( Function f , Impl impl , int pos ) {
15051530 methodResolutionDependsOnArgument ( impl , _, f , pos , _, _)
15061531}
15071532
1508- private class AssocFuncCallExpr extends CallExpr {
1533+ private class AssocFunctionCallExpr extends FunctionCallExpr {
15091534 private int pos ;
15101535
1511- AssocFuncCallExpr ( ) {
1536+ AssocFunctionCallExpr ( ) {
15121537 assocFuncResolutionDependsOnArgument ( CallExprImpl:: getResolvedFunction ( this ) , _, pos )
15131538 }
15141539
@@ -1524,11 +1549,11 @@ private class AssocFuncCallExpr extends CallExpr {
15241549}
15251550
15261551private module AssocFuncIsInstantiationOfInput implements
1527- IsInstantiationOfInputSig< AssocFuncCallExpr >
1552+ IsInstantiationOfInputSig< AssocFunctionCallExpr >
15281553{
15291554 pragma [ nomagic]
15301555 predicate potentialInstantiationOf (
1531- AssocFuncCallExpr ce , TypeAbstraction impl , TypeMention constraint
1556+ AssocFunctionCallExpr ce , TypeAbstraction impl , TypeMention constraint
15321557 ) {
15331558 exists ( Function cand |
15341559 cand = ce .getACandidate ( impl ) and
@@ -1537,21 +1562,34 @@ private module AssocFuncIsInstantiationOfInput implements
15371562 }
15381563}
15391564
1565+ /**
1566+ * Gets the target of `call`, where resolution does not rely on type inference.
1567+ */
15401568pragma [ nomagic]
1541- ItemNode resolveCallTargetSimple ( CallExpr ce ) {
1542- result = CallExprImpl:: getResolvedFunction ( ce ) and
1569+ private ItemNode resolveFunctionCallTargetSimple ( FunctionCallExpr call ) {
1570+ result = CallExprImpl:: getResolvedFunction ( call ) and
15431571 not assocFuncResolutionDependsOnArgument ( result , _, _)
15441572}
15451573
1574+ /**
1575+ * Gets the target of `call`, where resolution relies on type inference.
1576+ */
15461577pragma [ nomagic]
1547- Function resolveCallTargetComplex ( AssocFuncCallExpr ce ) {
1578+ private Function resolveFunctionCallTargetComplex ( AssocFunctionCallExpr call ) {
15481579 exists ( Impl impl |
1549- IsInstantiationOf< AssocFuncCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( ce ,
1580+ IsInstantiationOf< AssocFunctionCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( call ,
15501581 impl , _) and
1551- result = getMethodSuccessor ( impl , ce .getACandidate ( _) .getName ( ) .getText ( ) )
1582+ result = getMethodSuccessor ( impl , call .getACandidate ( _) .getName ( ) .getText ( ) )
15521583 )
15531584}
15541585
1586+ pragma [ inline]
1587+ private ItemNode resolveFunctionCallTarget ( FunctionCallExpr call ) {
1588+ result = resolveFunctionCallTargetSimple ( call )
1589+ or
1590+ result = resolveFunctionCallTargetComplex ( call )
1591+ }
1592+
15551593cached
15561594private module Cached {
15571595 private import codeql.rust.internal.CachedStages
@@ -1580,26 +1618,12 @@ private module Cached {
15801618 )
15811619 }
15821620
1583- /** Gets a method that the method call `mc` resolves to, if any. */
1584- cached
1585- Function resolveMethodCallTarget ( MethodCall mc ) {
1586- // The method comes from an `impl` block targeting the type of the receiver.
1587- result = getMethodFromImpl ( mc )
1588- or
1589- // The type of the receiver is a type parameter and the method comes from a
1590- // trait bound on the type parameter.
1591- result = getTypeParameterMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1592- or
1593- // The type of the receiver is an `impl Trait` type.
1594- result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1595- }
1596-
1597- /** Gets a method that the method call `mc` resolves to, if any. */
1621+ /** Gets a function that `call` resolves to, if any. */
15981622 cached
1599- Function resolveCallTarget ( CallExpr ce ) {
1600- result = resolveCallTargetSimple ( ce )
1623+ Function resolveCallTarget ( Call call ) {
1624+ result = resolveMethodCallTarget ( call )
16011625 or
1602- result = resolveCallTargetComplex ( ce )
1626+ result = resolveFunctionCallTarget ( call )
16031627 }
16041628
16051629 pragma [ inline]
@@ -1736,8 +1760,8 @@ private module Debug {
17361760 private Locatable getRelevantLocatable ( ) {
17371761 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
17381762 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
1739- filepath .matches ( "%/sqlx .rs" ) and
1740- startline = [ 56 .. 60 ]
1763+ filepath .matches ( "%/main .rs" ) and
1764+ startline = 120
17411765 )
17421766 }
17431767
0 commit comments