@@ -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
@@ -1221,12 +1219,22 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
12211219final class MethodCall extends Call {
12221220 MethodCall ( ) { exists ( this .getReceiver ( ) ) }
12231221
1222+ private Type getReceiverTypeAt ( TypePath path ) {
1223+ result = inferType ( super .getReceiver ( ) , path )
1224+ or
1225+ exists ( PathExpr pe , TypeMention tm |
1226+ pe = this .( CallExpr ) .getFunction ( ) and
1227+ tm = pe .getPath ( ) .getQualifier ( ) and
1228+ result = tm .resolveTypeAt ( path )
1229+ )
1230+ }
1231+
12241232 /** Gets the type of the receiver of the method call at `path`. */
12251233 Type getTypeAt ( TypePath path ) {
12261234 if this .receiverImplicitlyBorrowed ( )
12271235 then
12281236 exists ( TypePath path0 , Type t0 |
1229- t0 = inferType ( super . getReceiver ( ) , path0 ) and
1237+ t0 = this . getReceiverTypeAt ( path0 ) and
12301238 (
12311239 path0 .isCons ( TRefTypeParameter ( ) , path )
12321240 or
@@ -1254,10 +1262,14 @@ final class MethodCall extends Call {
12541262 t0 .( StructType ) .asItemNode ( ) instanceof StringStruct and
12551263 result .( StructType ) .asItemNode ( ) instanceof Builtins:: Str
12561264 )
1257- else result = inferType ( super . getReceiver ( ) , path )
1265+ else result = this . getReceiverTypeAt ( path )
12581266 }
12591267}
12601268
1269+ final private class FunctionCallExpr extends CallExpr {
1270+ FunctionCallExpr ( ) { not this instanceof MethodCall }
1271+ }
1272+
12611273/**
12621274 * Holds if a method for `type` with the name `name` and the arity `arity`
12631275 * exists in `impl`.
@@ -1497,15 +1509,28 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
14971509 result = getMethodSuccessor ( trait .getImplTraitTypeRepr ( ) , name )
14981510}
14991511
1512+ pragma [ nomagic]
1513+ private Function resolveMethodCallTarget ( MethodCall mc ) {
1514+ // The method comes from an `impl` block targeting the type of the receiver.
1515+ result = getMethodFromImpl ( mc )
1516+ or
1517+ // The type of the receiver is a type parameter and the method comes from a
1518+ // trait bound on the type parameter.
1519+ result = getTypeParameterMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1520+ or
1521+ // The type of the receiver is an `impl Trait` type.
1522+ result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1523+ }
1524+
15001525pragma [ nomagic]
15011526private predicate assocFuncResolutionDependsOnArgument ( Function f , Impl impl , int pos ) {
15021527 methodResolutionDependsOnArgument ( impl , _, f , pos , _, _)
15031528}
15041529
1505- private class AssocFuncCallExpr extends CallExpr {
1530+ private class AssocFunctionCallExpr extends FunctionCallExpr {
15061531 private int pos ;
15071532
1508- AssocFuncCallExpr ( ) {
1533+ AssocFunctionCallExpr ( ) {
15091534 assocFuncResolutionDependsOnArgument ( CallExprImpl:: getResolvedFunction ( this ) , _, pos )
15101535 }
15111536
@@ -1521,11 +1546,11 @@ private class AssocFuncCallExpr extends CallExpr {
15211546}
15221547
15231548private module AssocFuncIsInstantiationOfInput implements
1524- IsInstantiationOfInputSig< AssocFuncCallExpr >
1549+ IsInstantiationOfInputSig< AssocFunctionCallExpr >
15251550{
15261551 pragma [ nomagic]
15271552 predicate potentialInstantiationOf (
1528- AssocFuncCallExpr ce , TypeAbstraction impl , TypeMention constraint
1553+ AssocFunctionCallExpr ce , TypeAbstraction impl , TypeMention constraint
15291554 ) {
15301555 exists ( Function cand |
15311556 cand = ce .getACandidate ( impl ) and
@@ -1534,21 +1559,34 @@ private module AssocFuncIsInstantiationOfInput implements
15341559 }
15351560}
15361561
1562+ /**
1563+ * Gets the target of `call`, where resolution does not rely on type inference.
1564+ */
15371565pragma [ nomagic]
1538- ItemNode resolveCallTargetSimple ( CallExpr ce ) {
1539- result = CallExprImpl:: getResolvedFunction ( ce ) and
1566+ private ItemNode resolveFunctionCallTargetSimple ( FunctionCallExpr call ) {
1567+ result = CallExprImpl:: getResolvedFunction ( call ) and
15401568 not assocFuncResolutionDependsOnArgument ( result , _, _)
15411569}
15421570
1571+ /**
1572+ * Gets the target of `call`, where resolution relies on type inference.
1573+ */
15431574pragma [ nomagic]
1544- Function resolveCallTargetComplex ( AssocFuncCallExpr ce ) {
1575+ private Function resolveFunctionCallTargetComplex ( AssocFunctionCallExpr call ) {
15451576 exists ( Impl impl |
1546- IsInstantiationOf< AssocFuncCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( ce ,
1577+ IsInstantiationOf< AssocFunctionCallExpr , AssocFuncIsInstantiationOfInput > :: isInstantiationOf ( call ,
15471578 impl , _) and
1548- result = getMethodSuccessor ( impl , ce .getACandidate ( _) .getName ( ) .getText ( ) )
1579+ result = getMethodSuccessor ( impl , call .getACandidate ( _) .getName ( ) .getText ( ) )
15491580 )
15501581}
15511582
1583+ pragma [ inline]
1584+ private ItemNode resolveFunctionCallTarget ( FunctionCallExpr call ) {
1585+ result = resolveFunctionCallTargetSimple ( call )
1586+ or
1587+ result = resolveFunctionCallTargetComplex ( call )
1588+ }
1589+
15521590cached
15531591private module Cached {
15541592 private import codeql.rust.internal.CachedStages
@@ -1577,26 +1615,12 @@ private module Cached {
15771615 )
15781616 }
15791617
1580- /** Gets a method that the method call `mc` resolves to, if any. */
1581- cached
1582- Function resolveMethodCallTarget ( MethodCall mc ) {
1583- // The method comes from an `impl` block targeting the type of the receiver.
1584- result = getMethodFromImpl ( mc )
1585- or
1586- // The type of the receiver is a type parameter and the method comes from a
1587- // trait bound on the type parameter.
1588- result = getTypeParameterMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1589- or
1590- // The type of the receiver is an `impl Trait` type.
1591- result = getTraitMethod ( mc .getTypeAt ( TypePath:: nil ( ) ) , mc .getMethodName ( ) )
1592- }
1593-
1594- /** Gets a method that the method call `mc` resolves to, if any. */
1618+ /** Gets a function that `call` resolves to, if any. */
15951619 cached
1596- Function resolveCallTarget ( CallExpr ce ) {
1597- result = resolveCallTargetSimple ( ce )
1620+ Function resolveCallTarget ( Call call ) {
1621+ result = resolveMethodCallTarget ( call )
15981622 or
1599- result = resolveCallTargetComplex ( ce )
1623+ result = resolveFunctionCallTarget ( call )
16001624 }
16011625
16021626 pragma [ inline]
@@ -1733,8 +1757,8 @@ private module Debug {
17331757 private Locatable getRelevantLocatable ( ) {
17341758 exists ( string filepath , int startline , int startcolumn , int endline , int endcolumn |
17351759 result .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) and
1736- filepath .matches ( "%/sqlx .rs" ) and
1737- startline = [ 56 .. 60 ]
1760+ filepath .matches ( "%/main .rs" ) and
1761+ startline = 120
17381762 )
17391763 }
17401764
0 commit comments