Skip to content

Commit d206f73

Browse files
committed
wip2
1 parent 37e2526 commit d206f73

File tree

2 files changed

+63
-78
lines changed

2 files changed

+63
-78
lines changed

rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,20 @@ class FunctionPosition extends TFunctionPosition {
2929

3030
predicate isReturn() { this = TReturnFunctionPosition() }
3131

32-
/** Gets the corresponding position when `f` is invoked via a function call. */
33-
bindingset[f]
34-
FunctionPosition getFunctionCallAdjusted(Function f) {
32+
/** Gets the corresponding position when function call syntax is used. */
33+
FunctionPosition getFunctionCallAdjusted() {
3534
(this.isReturn() or this.isTypeQualifier()) and
3635
result = this
3736
or
38-
if f.hasSelfParam()
39-
then
40-
this.isSelf() and result.asPosition() = 0
41-
or
42-
result.asPosition() = this.asPosition() + 1
43-
else result = this
37+
this.isSelf() and result.asPosition() = 0
38+
or
39+
result.asPosition() = this.asPosition() + 1
40+
}
41+
42+
/** Gets the corresponding position when `f` is invoked via a function call. */
43+
bindingset[f]
44+
FunctionPosition getFunctionCallAdjusted(Function f) {
45+
if f.hasSelfParam() then result = this.getFunctionCallAdjusted() else result = this
4446
}
4547

4648
TypeMention getTypeMention(Function f) {

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

Lines changed: 52 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,16 +1394,22 @@ private module AssocFunctionResolution {
13941394

13951395
/**
13961396
* Holds if function `f` with the name `name` and the arity `arity` exists in
1397-
* `i`, and the type of the `self` parameter is `selfType`.
1397+
* `i`, and the type at `selfPos` and `strippedTypePath` is `selfType`.
1398+
*
1399+
* `selfPos` is one of the positions that can be used to resolve the call, for
1400+
* example the `self` parameter of a method or a position corresponding to `Self`
1401+
* trait type parameter.
13981402
*
13991403
* `strippedTypePath` points to the type `strippedType` inside `selfType`,
14001404
* which is the (possibly complex-stripped) root type of `selfType`. For example,
14011405
* if `f` has a `&self` parameter, then `strippedTypePath` is `getRefSharedTypeParameter()`
14021406
* and `strippedType` is the type inside the reference.
1407+
*
1408+
* `selfPosAdj` is the function-call adjusted version of `selfPos`.
14031409
*/
14041410
pragma[nomagic]
14051411
private predicate assocFunctionInfo(
1406-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1412+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14071413
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
14081414
) {
14091415
assocFunctionInfo(f, name, arity, i, selfPos, selfType) and
@@ -1413,7 +1419,7 @@ private module AssocFunctionResolution {
14131419
or
14141420
selfPos.isTypeQualifier() and strippedTypePath.isEmpty()
14151421
) and
1416-
posAdj = selfPos.getFunctionCallAdjusted(f) and
1422+
selfPosAdj = selfPos.getFunctionCallAdjusted(f) and
14171423
(
14181424
selfPos.isSelfOrTypeQualifier()
14191425
or
@@ -1425,10 +1431,10 @@ private module AssocFunctionResolution {
14251431

14261432
pragma[nomagic]
14271433
private predicate assocFunctionInfoTypeParam(
1428-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1434+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14291435
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, TypeParam tp
14301436
) {
1431-
assocFunctionInfo(f, name, arity, selfPos, posAdj, i, selfType, strippedTypePath,
1437+
assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
14321438
TTypeParamTypeParameter(tp))
14331439
}
14341440

@@ -1439,33 +1445,35 @@ private module AssocFunctionResolution {
14391445
*/
14401446
pragma[inline]
14411447
private predicate assocFunctionInfoNonBlanket(
1442-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1448+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14431449
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
14441450
) {
14451451
(
1446-
assocFunctionInfo(f, name, arity, selfPos, posAdj, i, selfType, strippedTypePath, strippedType) or
1447-
assocFunctionInfoTypeParam(f, name, arity, selfPos, posAdj, i, selfType, strippedTypePath, _)
1452+
assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
1453+
strippedType) or
1454+
assocFunctionInfoTypeParam(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
1455+
_)
14481456
) and
14491457
not BlanketImplementation::isBlanketLike(i, _, _)
14501458
}
14511459

14521460
/**
1453-
* Holds if function `f` with the name `name` and the arity `arity` exists in
1454-
* blanket (like) implementation `impl` of `trait`, and the type of the `self`
1455-
* parameter is `selfType`.
1461+
* Holds if associated function `f` with the name `name` and the arity `arity` exists
1462+
* in blanket (like) implementation `impl` of `trait`, and the type at `selfPos` and
1463+
* `blanketPath` is `selfType`.
14561464
*
14571465
* `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which
14581466
* is the type parameter used in the blanket implementation.
14591467
*/
14601468
pragma[nomagic]
14611469
private predicate assocFunctionSelfInfoBlanketLike(
1462-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1470+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14631471
ImplItemNode impl, Trait trait, AssocFunctionType selfType, TypePath blanketPath,
14641472
TypeParam blanketTypeParam
14651473
) {
14661474
assocFunctionInfoBlanketLike(f, name, arity, impl, trait, selfPos, selfType, blanketPath,
14671475
blanketTypeParam) and
1468-
posAdj = selfPos.getFunctionCallAdjusted(f) and
1476+
selfPosAdj = selfPos.getFunctionCallAdjusted(f) and
14691477
(
14701478
selfPos.isSelfOrTypeQualifier()
14711479
or
@@ -1522,12 +1530,12 @@ private module AssocFunctionResolution {
15221530
bindingset[mc, strippedTypePath, strippedType]
15231531
pragma[inline_late]
15241532
private predicate methodCallNonBlanketCandidate(
1525-
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition pos,
1533+
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj,
15261534
ImplOrTraitItemNode i, AssocFunctionType self, TypePath strippedTypePath, Type strippedType
15271535
) {
15281536
exists(string name, int arity |
15291537
mc.hasNameAndArity(name, arity) and
1530-
assocFunctionInfoNonBlanket(f, name, arity, selfPos, pos, i, self, strippedTypePath,
1538+
assocFunctionInfoNonBlanket(f, name, arity, selfPos, selfPosAdj, i, self, strippedTypePath,
15311539
strippedType) and
15321540
(if mc.hasReceiver() then f instanceof Method else any()) and
15331541
// todo: comment
@@ -1565,13 +1573,13 @@ private module AssocFunctionResolution {
15651573
bindingset[mc]
15661574
pragma[inline_late]
15671575
private predicate methodCallBlanketLikeCandidate(
1568-
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition pos, ImplItemNode impl,
1569-
AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam
1576+
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj,
1577+
ImplItemNode impl, AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam
15701578
) {
15711579
exists(string name, int arity |
15721580
mc.hasNameAndArity(name, arity) and
1573-
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, pos, impl, _, self, blanketPath,
1574-
blanketTypeParam) and
1581+
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, selfPosAdj, impl, _, self,
1582+
blanketPath, blanketTypeParam) and
15751583
if mc.hasReceiver() then f instanceof Method else any()
15761584
|
15771585
methodCallVisibleImplTraitCandidate(mc, impl)
@@ -2005,10 +2013,10 @@ private module AssocFunctionResolution {
20052013
*/
20062014
pragma[nomagic]
20072015
Function resolveCallTarget(
2008-
ImplOrTraitItemNode i, FunctionPosition pos, DerefChain derefChain, BorrowKind borrow
2016+
ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow
20092017
) {
20102018
exists(MethodCallCand mcc |
2011-
mcc = MkMethodCallCand(this, pos, _, derefChain, borrow) and
2019+
mcc = MkMethodCallCand(this, selfPos, _, derefChain, borrow) and
20122020
result = mcc.resolveCallTarget(i)
20132021
)
20142022
}
@@ -2171,32 +2179,25 @@ private module AssocFunctionResolution {
21712179

21722180
private newtype TMethodCallCand =
21732181
MkMethodCallCand(
2174-
MethodCall mc, FunctionPosition selfPos, FunctionPosition pos, DerefChain derefChain,
2182+
MethodCall mc, FunctionPosition selfPos, FunctionPosition selfPosAdj, DerefChain derefChain,
21752183
BorrowKind borrow
21762184
) {
21772185
// todo: restrict to relevant positions
21782186
exists(mc.getACandidateReceiverTypeAt(selfPos, derefChain, borrow, _)) and
21792187
if mc.hasReceiver()
2180-
then
2181-
pos.asPosition() = 0 and selfPos.isSelf()
2182-
or
2183-
pos.asPosition() = selfPos.asPosition() + 1
2184-
or
2185-
pos.isTypeQualifier() and selfPos.isTypeQualifier()
2186-
or
2187-
pos.isReturn() and selfPos.isReturn()
2188-
else pos = selfPos
2188+
then selfPosAdj = selfPos.getFunctionCallAdjusted()
2189+
else selfPosAdj = selfPos
21892190
}
21902191

21912192
/** A method call with a dereference chain and a potential borrow. */
21922193
private class MethodCallCand extends MkMethodCallCand {
21932194
MethodCall mc_;
2194-
FunctionPosition pos;
21952195
FunctionPosition selfPos;
2196+
FunctionPosition selfPosAdj;
21962197
DerefChain derefChain;
21972198
BorrowKind borrow;
21982199

2199-
MethodCallCand() { this = MkMethodCallCand(mc_, selfPos, pos, derefChain, borrow) }
2200+
MethodCallCand() { this = MkMethodCallCand(mc_, selfPos, selfPosAdj, derefChain, borrow) }
22002201

22012202
MethodCall getMethodCall() { result = mc_ }
22022203

@@ -2220,7 +2221,7 @@ private module AssocFunctionResolution {
22202221

22212222
pragma[nomagic]
22222223
predicate hasSignature(
2223-
MethodCall mc, FunctionPosition pos_, TypePath strippedTypePath, Type strippedType,
2224+
MethodCall mc, FunctionPosition pos, TypePath strippedTypePath, Type strippedType,
22242225
string name, int arity
22252226
) {
22262227
strippedType = this.getTypeAt(strippedTypePath) and
@@ -2231,7 +2232,7 @@ private module AssocFunctionResolution {
22312232
) and
22322233
mc = mc_ and
22332234
mc.hasNameAndArity(name, arity) and
2234-
pos = pos_
2235+
pos = selfPosAdj
22352236
}
22362237

22372238
/**
@@ -2252,10 +2253,11 @@ private module AssocFunctionResolution {
22522253
mc_.hasTrait()
22532254
or
22542255
exists(TypePath strippedTypePath, Type strippedType, string name, int arity |
2255-
(pos.isTypeQualifier() or pos.asPosition() = 0) and
2256-
this.hasSignature(_, pos, strippedTypePath, strippedType, name, arity) and
2256+
(selfPosAdj.isTypeQualifier() or selfPosAdj.asPosition() = 0) and
2257+
this.hasSignature(_, selfPosAdj, strippedTypePath, strippedType, name, arity) and
22572258
forall(Impl i |
2258-
assocFunctionInfoNonBlanket(_, name, arity, _, pos, i, _, strippedTypePath, strippedType) and
2259+
assocFunctionInfoNonBlanket(_, name, arity, _, selfPosAdj, i, _, strippedTypePath,
2260+
strippedType) and
22592261
not i.hasTrait()
22602262
|
22612263
this.hasIncompatibleInherentTarget(i)
@@ -2287,7 +2289,8 @@ private module AssocFunctionResolution {
22872289
}
22882290

22892291
string toString() {
2290-
result = mc_.toString() + " at " + pos + " [" + derefChain.toString() + "; " + borrow + "]"
2292+
result =
2293+
mc_.toString() + " at " + selfPos + " [" + derefChain.toString() + "; " + borrow + "]"
22912294
}
22922295

22932296
Location getLocation() { result = mc_.getLocation() }
@@ -2368,9 +2371,9 @@ private module AssocFunctionResolution {
23682371
predicate hasBlanketCandidate(
23692372
MethodCallCand mcc, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
23702373
) {
2371-
exists(MethodCall mc, FunctionPosition pos, BorrowKind borrow |
2372-
mcc = MkMethodCallCand(mc, _, pos, _, borrow) and
2373-
methodCallBlanketLikeCandidate(mc, _, _, pos, impl, _, blanketPath, blanketTypeParam) and
2374+
exists(MethodCall mc, FunctionPosition selfPosAdj, BorrowKind borrow |
2375+
mcc = MkMethodCallCand(mc, _, selfPosAdj, _, borrow) and
2376+
methodCallBlanketLikeCandidate(mc, _, _, selfPosAdj, impl, _, blanketPath, blanketTypeParam) and
23742377
// Only apply blanket implementations when no other implementations are possible;
23752378
// this is to account for codebases that use the (unstable) specialization feature
23762379
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
@@ -2444,9 +2447,9 @@ private module AssocFunctionResolution {
24442447
predicate potentialInstantiationOf(
24452448
MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint
24462449
) {
2447-
exists(MethodCall mc, FunctionPosition pos |
2448-
mcc = MkMethodCallCand(mc, _, pos, _, _) and
2449-
methodCallBlanketLikeCandidate(mc, _, _, pos, abs, constraint, _, _) and
2450+
exists(MethodCall mc, FunctionPosition selfPosAdj |
2451+
mcc = MkMethodCallCand(mc, _, selfPosAdj, _, _) and
2452+
methodCallBlanketLikeCandidate(mc, _, _, selfPosAdj, abs, constraint, _, _) and
24502453
if abs.(Impl).hasTrait()
24512454
then
24522455
// inherent methods take precedence over trait methods, so only allow
@@ -2474,8 +2477,8 @@ private module AssocFunctionResolution {
24742477
ReceiverIsInstantiationOfSelfParamInput::potentialInstantiationOf0(mcc, abs, constraint) and
24752478
abs = any(Impl i | not i.hasTrait()) and
24762479
// todo: comment
2477-
exists(FunctionPosition pos | mcc = MkMethodCallCand(_, _, pos, _, _) |
2478-
pos.isTypeQualifier() or pos.asPosition() = 0
2480+
exists(FunctionPosition selfPosAdj | mcc = MkMethodCallCand(_, _, selfPosAdj, _, _) |
2481+
selfPosAdj.isTypeQualifier() or selfPosAdj.asPosition() = 0
24792482
)
24802483
}
24812484
}
@@ -2623,17 +2626,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
26232626
)
26242627
|
26252628
// result = this.getInferredNonSelfType(pos, path)
2626-
if this.hasReceiver()
2627-
then apos = pos
2628-
else (
2629-
pos.asPosition() = 0 and apos.isSelf()
2630-
or
2631-
pos.asPosition() = apos.asPosition() + 1
2632-
or
2633-
pos.isTypeQualifier() and apos.isTypeQualifier()
2634-
or
2635-
pos.isReturn() and apos.isReturn()
2636-
)
2629+
if this.hasReceiver() then apos = pos else pos = apos.getFunctionCallAdjusted()
26372630
)
26382631
}
26392632

@@ -2689,17 +2682,7 @@ private Type inferMethodCallType0(
26892682
exists(TypePath path0 |
26902683
n = a.getNodeAt(apos) and
26912684
exists(FunctionPosition pos |
2692-
if a.hasReceiver()
2693-
then apos = pos
2694-
else (
2695-
apos.asPosition() = 0 and pos.isSelf()
2696-
or
2697-
apos.asPosition() = pos.asPosition() + 1
2698-
or
2699-
apos.isTypeQualifier() and pos.isTypeQualifier()
2700-
or
2701-
apos.isReturn() and pos.isReturn()
2702-
)
2685+
if a.hasReceiver() then apos = pos else apos = pos.getFunctionCallAdjusted()
27032686
|
27042687
exists(string derefChainBorrow |
27052688
MethodCallMatchingInput::decodeDerefChainBorrow(derefChainBorrow, _, derefChain, borrow)

0 commit comments

Comments
 (0)