@@ -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,21 @@ 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
1269+ if this .( CallImpl:: CallExprMethodCall ) .hasExplicitSelfBorrow ( )
1270+ then
1271+ exists ( TypePath path0 |
1272+ result = this .getReceiverTypeAt ( path0 ) and
1273+ path0 .isCons ( TRefTypeParameter ( ) , path )
1274+ )
1275+ else result = this .getReceiverTypeAt ( path )
12611276 }
12621277}
12631278
1279+ final private class FunctionCallExpr extends CallExpr {
1280+ FunctionCallExpr ( ) { not this instanceof MethodCall }
1281+ }
1282+
12641283/**
12651284 * Holds if a method for `type` with the name `name` and the arity `arity`
12661285 * exists in `impl`.
@@ -1500,15 +1519,28 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
15001519 result = getMethodSuccessor ( trait .getImplTraitTypeRepr ( ) , name )
15011520}
15021521
1522+ pragma [ nomagic]
1523+ private Function resolveMethodCallTarget ( MethodCall mc ) {
1524+ // The method comes from an `impl` block targeting the type of the receiver.
1525+ result = getMethodFromImpl ( mc )
1526+ or
1527+ // The type of the receiver is a type parameter and the method comes from a
1528+ // trait bound on the type parameter.
1529+ result = getTypeParameterMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1530+ or
1531+ // The type of the receiver is an `impl Trait` type.
1532+ result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1533+ }
1534+
15031535pragma [ nomagic]
15041536private predicate assocFuncResolutionDependsOnArgument ( Function f , Impl impl , int pos ) {
15051537 methodResolutionDependsOnArgument ( impl , _, f , pos , _, _)
15061538}
15071539
1508- private class AssocFuncCallExpr extends CallExpr {
1540+ private class AssocFunctionCallExpr extends FunctionCallExpr {
15091541 private int pos ;
15101542
1511- AssocFuncCallExpr ( ) {
1543+ AssocFunctionCallExpr ( ) {
15121544 assocFuncResolutionDependsOnArgument ( CallExprImpl:: getResolvedFunction ( this ) , _, pos )
15131545 }
15141546
@@ -1524,11 +1556,11 @@ private class AssocFuncCallExpr extends CallExpr {
15241556}
15251557
15261558private module AssocFuncIsInstantiationOfInput implements
1527- IsInstantiationOfInputSig< AssocFuncCallExpr >
1559+ IsInstantiationOfInputSig< AssocFunctionCallExpr >
15281560{
15291561 pragma [ nomagic]
15301562 predicate potentialInstantiationOf (
1531- AssocFuncCallExpr ce , TypeAbstraction impl , TypeMention constraint
1563+ AssocFunctionCallExpr ce , TypeAbstraction impl , TypeMention constraint
15321564 ) {
15331565 exists ( Function cand |
15341566 cand = ce .getACandidate ( impl ) and
@@ -1537,21 +1569,34 @@ private module AssocFuncIsInstantiationOfInput implements
15371569 }
15381570}
15391571
1572+ /**
1573+ * Gets the target of `call`, where resolution does not rely on type inference.
1574+ */
15401575pragma [ nomagic]
1541- ItemNode resolveCallTargetSimple ( CallExpr ce ) {
1542- result = CallExprImpl:: getResolvedFunction ( ce ) and
1576+ private ItemNode resolveFunctionCallTargetSimple ( FunctionCallExpr call ) {
1577+ result = CallExprImpl:: getResolvedFunction ( call ) and
15431578 not assocFuncResolutionDependsOnArgument ( result , _, _)
15441579}
15451580
1581+ /**
1582+ * Gets the target of `call`, where resolution relies on type inference.
1583+ */
15461584pragma [ nomagic]
1547- Function resolveCallTargetComplex ( AssocFuncCallExpr ce ) {
1585+ private Function resolveFunctionCallTargetComplex ( AssocFunctionCallExpr call ) {
15481586 exists ( Impl impl |
1549- IsInstantiationOf< AssocFuncCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( ce ,
1587+ IsInstantiationOf< AssocFunctionCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( call ,
15501588 impl , _) and
1551- result = getMethodSuccessor ( impl , ce .getACandidate ( _) .getName ( ) .getText ( ) )
1589+ result = getMethodSuccessor ( impl , call .getACandidate ( _) .getName ( ) .getText ( ) )
15521590 )
15531591}
15541592
1593+ pragma [ inline]
1594+ private ItemNode resolveFunctionCallTarget ( FunctionCallExpr call ) {
1595+ result = resolveFunctionCallTargetSimple ( call )
1596+ or
1597+ result = resolveFunctionCallTargetComplex ( call )
1598+ }
1599+
15551600cached
15561601private module Cached {
15571602 private import codeql.rust.internal.CachedStages
@@ -1580,26 +1625,12 @@ private module Cached {
15801625 )
15811626 }
15821627
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. */
1628+ /** Gets a function that `call` resolves to, if any. */
15981629 cached
1599- Function resolveCallTarget ( CallExpr ce ) {
1600- result = resolveCallTargetSimple ( ce )
1630+ Function resolveCallTarget ( Call call ) {
1631+ result = resolveMethodCallTarget ( call )
16011632 or
1602- result = resolveCallTargetComplex ( ce )
1633+ result = resolveFunctionCallTarget ( call )
16031634 }
16041635
16051636 pragma [ inline]
@@ -1736,8 +1767,8 @@ private module Debug {
17361767 private Locatable getRelevantLocatable ( ) {
17371768 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
17381769 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
1739- filepath .matches ( "%/sqlx .rs" ) and
1740- startline = [ 56 .. 60 ]
1770+ filepath .matches ( "%/main .rs" ) and
1771+ startline = 120
17411772 )
17421773 }
17431774
0 commit comments