Skip to content

Commit fc8ff54

Browse files
committed
wip
1 parent 75e0f48 commit fc8ff54

File tree

6 files changed

+85
-42
lines changed

6 files changed

+85
-42
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private import codeql.rust.elements.Resolvable
1313
*/
1414
module Impl {
1515
private import rust
16+
private import codeql.rust.internal.TypeInference as TypeInference
1617

1718
pragma[nomagic]
1819
Resolvable getCallResolvable(CallExprBase call) {
@@ -27,7 +28,11 @@ module Impl {
2728
*/
2829
class CallExprBase extends Generated::CallExprBase {
2930
/** Gets the static target of this call, if any. */
30-
Callable getStaticTarget() { none() } // overridden by subclasses, but cannot be made abstract
31+
final Callable getStaticTarget() {
32+
result = TypeInference::resolveMethodCallTarget(this)
33+
or
34+
result = TypeInference::resolveCallTarget(this)
35+
}
3136

3237
override Expr getArg(int index) { result = this.getArgList().getArg(index) }
3338
}

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ private import codeql.rust.elements.PathExpr
1414
module Impl {
1515
private import rust
1616
private import codeql.rust.internal.PathResolution as PathResolution
17-
private import codeql.rust.internal.TypeInference as TypeInference
1817

1918
pragma[nomagic]
2019
Path getFunctionPath(CallExpr ce) { result = ce.getFunction().(PathExpr).getPath() }
@@ -37,15 +36,6 @@ module Impl {
3736
class CallExpr extends Generated::CallExpr {
3837
override string toStringImpl() { result = this.getFunction().toAbbreviatedString() + "(...)" }
3938

40-
override Callable getStaticTarget() {
41-
// If this call is to a trait method, e.g., `Trait::foo(bar)`, then check
42-
// if type inference can resolve it to the correct trait implementation.
43-
result = TypeInference::resolveMethodCallTarget(this)
44-
or
45-
not exists(TypeInference::resolveMethodCallTarget(this)) and
46-
result = getResolvedFunction(this)
47-
}
48-
4939
/** Gets the struct that this call resolves to, if any. */
5040
Struct getStruct() { result = getResolvedFunction(this) }
5141

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ module Impl {
6262
Function getStaticTarget() {
6363
result = TypeInference::resolveMethodCallTarget(this)
6464
or
65-
not exists(TypeInference::resolveMethodCallTarget(this)) and
6665
result = this.(CallExpr).getStaticTarget()
6766
}
6867

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
private import rust
88
private import codeql.rust.elements.internal.generated.MethodCallExpr
9-
private import codeql.rust.internal.PathResolution
10-
private import codeql.rust.internal.TypeInference
119

1210
/**
1311
* INTERNAL: This module contains the customizable definition of `MethodCallExpr` and should not
@@ -23,8 +21,6 @@ module Impl {
2321
* ```
2422
*/
2523
class MethodCallExpr extends Generated::MethodCallExpr {
26-
override Function getStaticTarget() { result = resolveMethodCallTarget(this) }
27-
2824
private string toStringPart(int index) {
2925
index = 0 and
3026
result = this.getReceiver().toAbbreviatedString()

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

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import codeql.rust.frameworks.stdlib.Stdlib
1111
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
1212
private import codeql.rust.elements.Call
1313
private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl
14+
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
1415

1516
class 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

@@ -1284,7 +1285,7 @@ private predicate implSiblingCandidate(
12841285
// siblings).
12851286
not exists(impl.getAttributeMacroExpansion()) and
12861287
// We use this for resolving methods, so exclude traits that do not have methods.
1287-
exists(Function f | f = trait.getASuccessor(_) and f.getParamList().hasSelfParam()) and
1288+
exists(Function f | f = trait.getASuccessor(_)) and
12881289
selfTy = impl.getSelfTy() and
12891290
rootType = selfTy.resolveType()
12901291
}
@@ -1433,6 +1434,58 @@ private Function getTraitMethod(ImplTraitReturnType trait, string name) {
14331434
result = getMethodSuccessor(trait.getImplTraitTypeRepr(), name)
14341435
}
14351436

1437+
pragma[nomagic]
1438+
private predicate assocFuncResolutionDependsOnArgument(Function f, Impl impl, int pos) {
1439+
methodResolutionDependsOnArgument(impl, _, f, pos, _, _)
1440+
}
1441+
1442+
private class AssocFuncCallExpr extends CallExpr {
1443+
private int pos;
1444+
1445+
AssocFuncCallExpr() {
1446+
assocFuncResolutionDependsOnArgument(CallExprImpl::getResolvedFunction(this), _, pos)
1447+
}
1448+
1449+
Function getACandidate(Impl impl) {
1450+
result = CallExprImpl::getResolvedFunction(this) and
1451+
assocFuncResolutionDependsOnArgument(result, impl, pos)
1452+
}
1453+
1454+
int getPosition() { result = pos }
1455+
1456+
/** Gets the type of the receiver of the associated function call at `path`. */
1457+
Type getTypeAt(TypePath path) { result = inferType(this.getArg(pos), path) }
1458+
}
1459+
1460+
private module AssocFuncIsInstantiationOfInput implements
1461+
IsInstantiationOfInputSig<AssocFuncCallExpr>
1462+
{
1463+
pragma[nomagic]
1464+
predicate potentialInstantiationOf(
1465+
AssocFuncCallExpr ce, TypeAbstraction impl, TypeMention constraint
1466+
) {
1467+
exists(Function cand |
1468+
cand = ce.getACandidate(impl) and
1469+
constraint = cand.getParam(ce.getPosition()).getTypeRepr()
1470+
)
1471+
}
1472+
}
1473+
1474+
pragma[nomagic]
1475+
ItemNode resolveCallTargetSimple(CallExpr ce) {
1476+
result = CallExprImpl::getResolvedFunction(ce) and
1477+
not assocFuncResolutionDependsOnArgument(result, _, _)
1478+
}
1479+
1480+
pragma[nomagic]
1481+
Function resolveCallTargetComplex(AssocFuncCallExpr ce) {
1482+
exists(Impl impl |
1483+
IsInstantiationOf<AssocFuncCallExpr, AssocFuncIsInstantiationOfInput>::isInstantiationOf(ce,
1484+
impl, _) and
1485+
result = getMethodSuccessor(impl, ce.getACandidate(_).getName().getText())
1486+
)
1487+
}
1488+
14361489
cached
14371490
private module Cached {
14381491
private import codeql.rust.internal.CachedStages
@@ -1475,6 +1528,14 @@ private module Cached {
14751528
result = getTraitMethod(mc.getTypeAt(TypePath::nil()), mc.getMethodName())
14761529
}
14771530

1531+
/** Gets a method that the method call `mc` resolves to, if any. */
1532+
cached
1533+
Function resolveCallTarget(CallExpr ce) {
1534+
result = resolveCallTargetSimple(ce)
1535+
or
1536+
result = resolveCallTargetComplex(ce)
1537+
}
1538+
14781539
pragma[inline]
14791540
private Type inferRootTypeDeref(AstNode n) {
14801541
result = inferType(n) and

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

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,23 +3098,19 @@ inferType
30983098
| main.rs:2103:25:2103:28 | 3i64 | | {EXTERNAL LOCATION} | i64 |
30993099
| main.rs:2105:13:2105:13 | x | | {EXTERNAL LOCATION} | i64 |
31003100
| main.rs:2105:17:2105:35 | ...::my_from(...) | | {EXTERNAL LOCATION} | i64 |
3101-
| main.rs:2105:30:2105:34 | 73i64 | | {EXTERNAL LOCATION} | bool |
31023101
| main.rs:2105:30:2105:34 | 73i64 | | {EXTERNAL LOCATION} | i64 |
31033102
| main.rs:2106:13:2106:13 | y | | {EXTERNAL LOCATION} | i64 |
31043103
| main.rs:2106:17:2106:34 | ...::my_from(...) | | {EXTERNAL LOCATION} | i64 |
31053104
| main.rs:2106:30:2106:33 | true | | {EXTERNAL LOCATION} | bool |
3106-
| main.rs:2106:30:2106:33 | true | | {EXTERNAL LOCATION} | i64 |
31073105
| main.rs:2107:13:2107:13 | z | | {EXTERNAL LOCATION} | i64 |
31083106
| main.rs:2107:13:2107:13 | z | | main.rs:2049:5:2052:5 | trait MyFrom |
31093107
| main.rs:2107:22:2107:43 | ...::my_from(...) | | {EXTERNAL LOCATION} | i64 |
31103108
| main.rs:2107:22:2107:43 | ...::my_from(...) | | main.rs:2049:5:2052:5 | trait MyFrom |
31113109
| main.rs:2107:38:2107:42 | 73i64 | | {EXTERNAL LOCATION} | bool |
31123110
| main.rs:2107:38:2107:42 | 73i64 | | {EXTERNAL LOCATION} | i64 |
3113-
| main.rs:2108:23:2108:27 | 73i64 | | {EXTERNAL LOCATION} | bool |
31143111
| main.rs:2108:23:2108:27 | 73i64 | | {EXTERNAL LOCATION} | i64 |
31153112
| main.rs:2108:30:2108:33 | 0i64 | | {EXTERNAL LOCATION} | i64 |
31163113
| main.rs:2109:23:2109:26 | true | | {EXTERNAL LOCATION} | bool |
3117-
| main.rs:2109:23:2109:26 | true | | {EXTERNAL LOCATION} | i64 |
31183114
| main.rs:2109:29:2109:32 | 0i64 | | {EXTERNAL LOCATION} | i64 |
31193115
| main.rs:2110:27:2110:31 | 73i64 | | {EXTERNAL LOCATION} | bool |
31203116
| main.rs:2110:27:2110:31 | 73i64 | | {EXTERNAL LOCATION} | i64 |
@@ -3226,35 +3222,21 @@ inferType
32263222
| main.rs:2149:18:2149:25 | strings1 | | file://:0:0:0:0 | [] |
32273223
| main.rs:2149:18:2149:25 | strings1 | [T;...] | {EXTERNAL LOCATION} | str |
32283224
| main.rs:2151:13:2151:20 | strings2 | | file://:0:0:0:0 | [] |
3229-
| main.rs:2151:13:2151:20 | strings2 | [T;...] | {EXTERNAL LOCATION} | String |
32303225
| main.rs:2152:9:2156:9 | [...] | | file://:0:0:0:0 | [] |
3231-
| main.rs:2152:9:2156:9 | [...] | [T;...] | {EXTERNAL LOCATION} | String |
3232-
| main.rs:2153:13:2153:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32333226
| main.rs:2153:26:2153:30 | "foo" | | {EXTERNAL LOCATION} | str |
3234-
| main.rs:2154:13:2154:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32353227
| main.rs:2154:26:2154:30 | "bar" | | {EXTERNAL LOCATION} | str |
3236-
| main.rs:2155:13:2155:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32373228
| main.rs:2155:26:2155:30 | "baz" | | {EXTERNAL LOCATION} | str |
3238-
| main.rs:2157:13:2157:13 | s | | {EXTERNAL LOCATION} | String |
32393229
| main.rs:2157:18:2157:25 | strings2 | | file://:0:0:0:0 | [] |
3240-
| main.rs:2157:18:2157:25 | strings2 | [T;...] | {EXTERNAL LOCATION} | String |
32413230
| main.rs:2159:13:2159:20 | strings3 | | file://:0:0:0:0 | & |
32423231
| main.rs:2159:13:2159:20 | strings3 | &T | file://:0:0:0:0 | [] |
3243-
| main.rs:2159:13:2159:20 | strings3 | &T.[T;...] | {EXTERNAL LOCATION} | String |
32443232
| main.rs:2160:9:2164:9 | &... | | file://:0:0:0:0 | & |
32453233
| main.rs:2160:9:2164:9 | &... | &T | file://:0:0:0:0 | [] |
3246-
| main.rs:2160:9:2164:9 | &... | &T.[T;...] | {EXTERNAL LOCATION} | String |
32473234
| main.rs:2160:10:2164:9 | [...] | | file://:0:0:0:0 | [] |
3248-
| main.rs:2160:10:2164:9 | [...] | [T;...] | {EXTERNAL LOCATION} | String |
3249-
| main.rs:2161:13:2161:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32503235
| main.rs:2161:26:2161:30 | "foo" | | {EXTERNAL LOCATION} | str |
3251-
| main.rs:2162:13:2162:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32523236
| main.rs:2162:26:2162:30 | "bar" | | {EXTERNAL LOCATION} | str |
3253-
| main.rs:2163:13:2163:31 | ...::from(...) | | {EXTERNAL LOCATION} | String |
32543237
| main.rs:2163:26:2163:30 | "baz" | | {EXTERNAL LOCATION} | str |
32553238
| main.rs:2165:18:2165:25 | strings3 | | file://:0:0:0:0 | & |
32563239
| main.rs:2165:18:2165:25 | strings3 | &T | file://:0:0:0:0 | [] |
3257-
| main.rs:2165:18:2165:25 | strings3 | &T.[T;...] | {EXTERNAL LOCATION} | String |
32583240
| main.rs:2167:13:2167:21 | callables | | file://:0:0:0:0 | [] |
32593241
| main.rs:2167:13:2167:21 | callables | [T;...] | main.rs:2115:5:2115:24 | MyCallable |
32603242
| main.rs:2167:25:2167:81 | [...] | | file://:0:0:0:0 | [] |
@@ -3316,10 +3298,8 @@ inferType
33163298
| main.rs:2196:32:2196:32 | 3 | | {EXTERNAL LOCATION} | u16 |
33173299
| main.rs:2199:13:2199:17 | vals5 | | {EXTERNAL LOCATION} | Vec |
33183300
| main.rs:2199:13:2199:17 | vals5 | A | {EXTERNAL LOCATION} | Global |
3319-
| main.rs:2199:13:2199:17 | vals5 | T | {EXTERNAL LOCATION} | u8 |
33203301
| main.rs:2199:21:2199:43 | ...::from(...) | | {EXTERNAL LOCATION} | Vec |
33213302
| main.rs:2199:21:2199:43 | ...::from(...) | A | {EXTERNAL LOCATION} | Global |
3322-
| main.rs:2199:21:2199:43 | ...::from(...) | T | {EXTERNAL LOCATION} | u8 |
33233303
| main.rs:2199:31:2199:42 | [...] | | file://:0:0:0:0 | [] |
33243304
| main.rs:2199:31:2199:42 | [...] | [T;...] | {EXTERNAL LOCATION} | i32 |
33253305
| main.rs:2199:31:2199:42 | [...] | [T;...] | {EXTERNAL LOCATION} | u32 |
@@ -3329,10 +3309,8 @@ inferType
33293309
| main.rs:2199:38:2199:38 | 2 | | {EXTERNAL LOCATION} | u32 |
33303310
| main.rs:2199:41:2199:41 | 3 | | {EXTERNAL LOCATION} | i32 |
33313311
| main.rs:2199:41:2199:41 | 3 | | {EXTERNAL LOCATION} | u32 |
3332-
| main.rs:2200:13:2200:13 | u | | {EXTERNAL LOCATION} | u8 |
33333312
| main.rs:2200:18:2200:22 | vals5 | | {EXTERNAL LOCATION} | Vec |
33343313
| main.rs:2200:18:2200:22 | vals5 | A | {EXTERNAL LOCATION} | Global |
3335-
| main.rs:2200:18:2200:22 | vals5 | T | {EXTERNAL LOCATION} | u8 |
33363314
| main.rs:2202:13:2202:17 | vals6 | | {EXTERNAL LOCATION} | Vec |
33373315
| main.rs:2202:13:2202:17 | vals6 | A | {EXTERNAL LOCATION} | Global |
33383316
| main.rs:2202:13:2202:17 | vals6 | T | file://:0:0:0:0 | & |
@@ -3510,3 +3488,17 @@ inferType
35103488
| main.rs:2291:41:2291:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo |
35113489
| main.rs:2307:5:2307:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future |
35123490
testFailures
3491+
| main.rs:120:17:120:40 | ...::trait_method(...) | Unexpected result: method=trait_method |
3492+
| main.rs:2105:38:2105:110 | //... | Fixed spurious result: method=MyFrom<bool>::my_from |
3493+
| main.rs:2106:37:2106:109 | //... | Fixed spurious result: method=MyFrom<i64>::my_from |
3494+
| main.rs:2108:37:2108:113 | //... | Fixed spurious result: method=MyFrom2<bool>::my_from2 |
3495+
| main.rs:2109:36:2109:112 | //... | Fixed spurious result: method=MyFrom2<i64>::my_from2 |
3496+
| main.rs:2151:24:2151:56 | //... | Missing result: type=strings2:[T;...].String |
3497+
| main.rs:2153:34:2153:49 | //... | Missing result: method=from |
3498+
| main.rs:2154:34:2154:49 | //... | Missing result: method=from |
3499+
| main.rs:2155:34:2155:49 | //... | Missing result: method=from |
3500+
| main.rs:2157:30:2157:47 | //... | Missing result: type=s:String |
3501+
| main.rs:2159:24:2159:59 | //... | Missing result: type=strings3:&T.[T;...].String |
3502+
| main.rs:2161:34:2161:49 | //... | Missing result: method=from |
3503+
| main.rs:2162:34:2162:49 | //... | Missing result: method=from |
3504+
| main.rs:2163:34:2163:49 | //... | Missing result: method=from |

0 commit comments

Comments
 (0)