Skip to content

Commit f3838d9

Browse files
committed
wip
1 parent 7167c8e commit f3838d9

File tree

5 files changed

+61
-48
lines changed

5 files changed

+61
-48
lines changed

rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,7 @@ module Impl {
2828
*/
2929
class CallExprBase extends Generated::CallExprBase {
3030
/** Gets the static target of this call, if any. */
31-
final Callable getStaticTarget() {
32-
result = TypeInference::resolveMethodCallTarget(this)
33-
or
34-
result = TypeInference::resolveCallTarget(this)
35-
}
31+
final Function getStaticTarget() { result = TypeInference::resolveCallTarget(this) }
3632

3733
override Expr getArg(int index) { result = this.getArgList().getArg(index) }
3834
}

rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ module Impl {
5959
Expr getReceiver() { result = this.getArgument(TSelfArgumentPosition()) }
6060

6161
/** Gets the static target of this call, if any. */
62-
Function getStaticTarget() {
63-
result = TypeInference::resolveMethodCallTarget(this)
64-
or
65-
result = this.(CallExpr).getStaticTarget()
66-
}
62+
Function getStaticTarget() { result = TypeInference::resolveCallTarget(this) }
6763

6864
/** Gets a runtime target of this call, if any. */
6965
pragma[nomagic]

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {
12211219
final 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+
15001525
pragma[nomagic]
15011526
private 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

15231548
private 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+
*/
15371565
pragma[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+
*/
15431574
pragma[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+
15521590
cached
15531591
private 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

rust/ql/test/library-tests/type-inference/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ mod trait_impl {
117117
let a = x.trait_method(); // $ type=a:bool method=MyThing::trait_method
118118

119119
let y = MyThing { field: false };
120-
let b = MyTrait::trait_method(y); // $ type=b:bool method=MyThing::trait_method $ SPURIOUS: method=trait_method
120+
let b = MyTrait::trait_method(y); // $ type=b:bool method=MyThing::trait_method
121121
}
122122
}
123123

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,11 @@ inferType
273273
| main.rs:117:17:117:17 | x | | main.rs:99:5:102:5 | MyThing |
274274
| main.rs:117:17:117:32 | x.trait_method() | | {EXTERNAL LOCATION} | bool |
275275
| main.rs:119:13:119:13 | y | | main.rs:99:5:102:5 | MyThing |
276-
| main.rs:119:13:119:13 | y | | main.rs:104:5:106:5 | trait MyTrait |
277276
| main.rs:119:17:119:40 | MyThing {...} | | main.rs:99:5:102:5 | MyThing |
278-
| main.rs:119:17:119:40 | MyThing {...} | | main.rs:104:5:106:5 | trait MyTrait |
279277
| main.rs:119:34:119:38 | false | | {EXTERNAL LOCATION} | bool |
280278
| main.rs:120:13:120:13 | b | | {EXTERNAL LOCATION} | bool |
281279
| main.rs:120:17:120:40 | ...::trait_method(...) | | {EXTERNAL LOCATION} | bool |
282280
| main.rs:120:39:120:39 | y | | main.rs:99:5:102:5 | MyThing |
283-
| main.rs:120:39:120:39 | y | | main.rs:104:5:106:5 | trait MyTrait |
284281
| main.rs:137:15:137:18 | SelfParam | | main.rs:125:5:128:5 | MyThing |
285282
| main.rs:137:15:137:18 | SelfParam | A | main.rs:130:5:131:14 | S1 |
286283
| main.rs:137:27:139:9 | { ... } | | main.rs:130:5:131:14 | S1 |

0 commit comments

Comments
 (0)