Skip to content

Commit eabd418

Browse files
committed
wip3
1 parent 825de5e commit eabd418

File tree

2 files changed

+68
-46
lines changed

2 files changed

+68
-46
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class FunctionPosition extends TFunctionPosition {
3232
/** Gets the corresponding position when `f` is invoked via a function call. */
3333
bindingset[f]
3434
FunctionPosition getFunctionCallAdjusted(Function f) {
35-
this.isReturn() and
35+
(this.isReturn() or this.isTypeQualifier()) and
3636
result = this
3737
or
3838
if f.hasSelfParam()

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

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,14 +1401,15 @@ private module MethodResolution {
14011401
*/
14021402
pragma[inline]
14031403
private predicate assocFunctionInfoNonBlanket(
1404-
Function f, string name, int arity, FunctionPosition selfPos, ImplOrTraitItemNode i,
1405-
AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
1404+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition pos,
1405+
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
14061406
) {
14071407
(
14081408
assocFunctionInfo(f, name, arity, selfPos, i, selfType, strippedTypePath, strippedType) or
14091409
assocFunctionInfoTypeParam(f, name, arity, selfPos, i, selfType, strippedTypePath, _)
14101410
) and
1411-
not BlanketImplementation::isBlanketLike(i, _, _)
1411+
not BlanketImplementation::isBlanketLike(i, _, _) and
1412+
pos = selfPos.getFunctionCallAdjusted(f)
14121413
}
14131414

14141415
/**
@@ -1421,12 +1422,14 @@ private module MethodResolution {
14211422
*/
14221423
pragma[nomagic]
14231424
private predicate assocFunctionSelfInfoBlanketLike(
1424-
Function f, string name, int arity, FunctionPosition selfPos, ImplItemNode impl, Trait trait,
1425-
AssocFunctionType selfType, TypePath blanketPath, TypeParam blanketTypeParam
1425+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1426+
ImplItemNode impl, Trait trait, AssocFunctionType selfType, TypePath blanketPath,
1427+
TypeParam blanketTypeParam
14261428
) {
14271429
assocFunctionInfoBlanketLike(f, name, arity, impl, trait, selfPos, selfType, blanketPath,
14281430
blanketTypeParam) and
1429-
selfPos.isSelfOrTypeQualifier()
1431+
selfPos.isSelfOrTypeQualifier() and
1432+
posAdj = selfPos.getFunctionCallAdjusted(f)
14301433
}
14311434

14321435
pragma[nomagic]
@@ -1478,12 +1481,13 @@ private module MethodResolution {
14781481
bindingset[mc, strippedTypePath, strippedType]
14791482
pragma[inline_late]
14801483
private predicate methodCallNonBlanketCandidate(
1481-
MethodCall mc, Function f, FunctionPosition selfPos, ImplOrTraitItemNode i,
1482-
AssocFunctionType self, TypePath strippedTypePath, Type strippedType
1484+
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition pos,
1485+
ImplOrTraitItemNode i, AssocFunctionType self, TypePath strippedTypePath, Type strippedType
14831486
) {
14841487
exists(string name, int arity |
14851488
mc.hasNameAndArity(name, arity) and
1486-
assocFunctionInfoNonBlanket(f, name, arity, selfPos, i, self, strippedTypePath, strippedType)
1489+
assocFunctionInfoNonBlanket(f, name, arity, selfPos, pos, i, self, strippedTypePath,
1490+
strippedType)
14871491
|
14881492
i =
14891493
any(Impl impl |
@@ -1512,12 +1516,12 @@ private module MethodResolution {
15121516
bindingset[mc]
15131517
pragma[inline_late]
15141518
private predicate methodCallBlanketLikeCandidate(
1515-
MethodCall mc, Function f, FunctionPosition selfPos, ImplItemNode impl, AssocFunctionType self,
1516-
TypePath blanketPath, TypeParam blanketTypeParam
1519+
MethodCall mc, Function f, FunctionPosition selfPos, FunctionPosition pos, ImplItemNode impl,
1520+
AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam
15171521
) {
15181522
exists(string name, int arity |
15191523
mc.hasNameAndArity(name, arity) and
1520-
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, impl, _, self, blanketPath,
1524+
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, pos, impl, _, self, blanketPath,
15211525
blanketTypeParam)
15221526
|
15231527
methodCallVisibleImplTraitCandidate(mc, impl)
@@ -1551,6 +1555,8 @@ private module MethodResolution {
15511555

15521556
abstract Expr getArg(ArgumentPosition pos);
15531557

1558+
predicate hasReceiver() { exists(this.getArg(any(ArgumentPosition self | self.isSelf()))) }
1559+
15541560
abstract predicate supportsAutoDerefAndBorrow();
15551561

15561562
/** Gets the trait targeted by this call, if any. */
@@ -1577,7 +1583,6 @@ private module MethodResolution {
15771583
FunctionPosition selfPos, DerefChain derefChain, TypePath path
15781584
) {
15791585
result = this.getArgumentTypeAt(selfPos.asArgumentPosition(), path) and
1580-
selfPos.isSelfOrTypeQualifier() and
15811586
derefChain.isEmpty()
15821587
or
15831588
exists(DerefImplItemNode impl, DerefChain suffix |
@@ -1602,7 +1607,7 @@ private module MethodResolution {
16021607
) {
16031608
exists(TypePath path |
16041609
ReceiverIsInstantiationOfSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this, selfPos,
1605-
derefChain, borrow), i, _, path) and
1610+
_, derefChain, borrow), i, _, path) and
16061611
path.isCons(root.getATypeParameter(), _)
16071612
)
16081613
}
@@ -1618,10 +1623,10 @@ private module MethodResolution {
16181623
ImplItemNode impl, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow
16191624
) {
16201625
ReceiverIsNotInstantiationOfBlanketLikeSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this,
1621-
selfPos, derefChain, borrow), impl, _, _)
1626+
selfPos, _, derefChain, borrow), impl, _, _)
16221627
or
16231628
ReceiverSatisfiesBlanketLikeConstraint::dissatisfiesBlanketConstraint(MkMethodCallCand(this,
1624-
selfPos, derefChain, borrow), impl)
1629+
selfPos, _, derefChain, borrow), impl)
16251630
}
16261631

16271632
/**
@@ -1651,7 +1656,7 @@ private module MethodResolution {
16511656
Type strippedType
16521657
) {
16531658
forall(ImplOrTraitItemNode i |
1654-
methodCallNonBlanketCandidate(this, _, selfPos, i, _, strippedTypePath, strippedType)
1659+
methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType)
16551660
|
16561661
this.hasIncompatibleTarget(i, selfPos, derefChain, borrow, strippedType)
16571662
)
@@ -1664,7 +1669,7 @@ private module MethodResolution {
16641669
) {
16651670
this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, borrow, strippedTypePath,
16661671
strippedType) and
1667-
forall(ImplItemNode i | methodCallBlanketLikeCandidate(this, _, selfPos, i, _, _, _) |
1672+
forall(ImplItemNode i | methodCallBlanketLikeCandidate(this, _, selfPos, _, i, _, _, _) |
16681673
this.hasIncompatibleBlanketLikeTarget(i, selfPos, derefChain, borrow)
16691674
)
16701675
}
@@ -1677,7 +1682,7 @@ private module MethodResolution {
16771682
this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, borrow, strippedTypePath,
16781683
strippedType) and
16791684
forall(ImplItemNode i |
1680-
methodCallBlanketLikeCandidate(this, _, selfPos, i, _, _, _) and
1685+
methodCallBlanketLikeCandidate(this, _, selfPos, _, i, _, _, _) and
16811686
not i.isBlanketImplementation()
16821687
|
16831688
this.hasIncompatibleBlanketLikeTarget(i, selfPos, derefChain, borrow)
@@ -1691,7 +1696,8 @@ private module MethodResolution {
16911696
int n
16921697
) {
16931698
(
1694-
this.supportsAutoDerefAndBorrow()
1699+
this.supportsAutoDerefAndBorrow() and
1700+
selfPos.isSelf()
16951701
or
16961702
// needed for the `hasNoCompatibleTarget` check in
16971703
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
@@ -1727,7 +1733,8 @@ private module MethodResolution {
17271733
int n
17281734
) {
17291735
(
1730-
this.supportsAutoDerefAndBorrow()
1736+
this.supportsAutoDerefAndBorrow() and
1737+
selfPos.isSelf()
17311738
or
17321739
// needed for the `hasNoCompatibleTarget` check in
17331740
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
@@ -1909,6 +1916,7 @@ private module MethodResolution {
19091916
exists(RefType rt |
19101917
// first try shared borrow
19111918
this.supportsAutoDerefAndBorrow() and
1919+
selfPos.isSelf() and
19121920
this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and
19131921
borrow.isSharedBorrow()
19141922
or
@@ -1937,7 +1945,7 @@ private module MethodResolution {
19371945
pragma[nomagic]
19381946
Function resolveCallTarget(ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow) {
19391947
exists(MethodCallCand mcc |
1940-
mcc = MkMethodCallCand(this, _, derefChain, borrow) and
1948+
mcc = MkMethodCallCand(this, _, _, derefChain, borrow) and
19411949
result = mcc.resolveCallTarget(i)
19421950
)
19431951
}
@@ -2031,7 +2039,7 @@ private module MethodResolution {
20312039
pragma[nomagic]
20322040
predicate hasNoInherentTarget() {
20332041
// `_` is fine below, because auto-deref/borrow is not supported
2034-
MkMethodCallCand(this, _, _, _).(MethodCallCand).hasNoInherentTarget()
2042+
MkMethodCallCand(this, _, _, _, _).(MethodCallCand).hasNoInherentTarget()
20352043
}
20362044

20372045
override predicate supportsAutoDerefAndBorrow() { none() }
@@ -2107,19 +2115,32 @@ private module MethodResolution {
21072115

21082116
private newtype TMethodCallCand =
21092117
MkMethodCallCand(
2110-
MethodCall mc, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow
2118+
MethodCall mc, FunctionPosition selfPos, FunctionPosition pos, DerefChain derefChain,
2119+
BorrowKind borrow
21112120
) {
2112-
exists(mc.getACandidateReceiverTypeAt(selfPos, derefChain, borrow, _))
2121+
exists(mc.getACandidateReceiverTypeAt(selfPos, derefChain, borrow, _)) and
2122+
if mc.hasReceiver()
2123+
then
2124+
pos.asPosition() = 0 and selfPos.isSelf()
2125+
or
2126+
pos.asPosition() = selfPos.asPosition() + 1
2127+
or
2128+
pos.isTypeQualifier() and selfPos.isTypeQualifier()
2129+
else
2130+
// or
2131+
// pos.isReturn() and selfPos.isReturn()
2132+
pos = selfPos
21132133
}
21142134

21152135
/** A method call with a dereference chain and a potential borrow. */
21162136
private class MethodCallCand extends MkMethodCallCand {
21172137
MethodCall mc_;
2138+
FunctionPosition pos;
21182139
FunctionPosition selfPos;
21192140
DerefChain derefChain;
21202141
BorrowKind borrow;
21212142

2122-
MethodCallCand() { this = MkMethodCallCand(mc_, selfPos, derefChain, borrow) }
2143+
MethodCallCand() { this = MkMethodCallCand(mc_, selfPos, pos, derefChain, borrow) }
21232144

21242145
MethodCall getMethodCall() { result = mc_ }
21252146

@@ -2143,14 +2164,14 @@ private module MethodResolution {
21432164

21442165
pragma[nomagic]
21452166
predicate hasSignature(
2146-
MethodCall mc, FunctionPosition selfPos_, TypePath strippedTypePath, Type strippedType,
2167+
MethodCall mc, FunctionPosition pos_, TypePath strippedTypePath, Type strippedType,
21472168
string name, int arity
21482169
) {
21492170
strippedType = this.getTypeAt(strippedTypePath) and
21502171
isComplexRootStripped(strippedTypePath, strippedType) and
21512172
mc = mc_ and
21522173
mc.hasNameAndArity(name, arity) and
2153-
selfPos = selfPos_
2174+
pos = pos_
21542175
}
21552176

21562177
/**
@@ -2171,9 +2192,9 @@ private module MethodResolution {
21712192
mc_.hasTrait()
21722193
or
21732194
exists(TypePath strippedTypePath, Type strippedType, string name, int arity |
2174-
this.hasSignature(_, selfPos, strippedTypePath, strippedType, name, arity) and
2195+
this.hasSignature(_, pos, strippedTypePath, strippedType, name, arity) and
21752196
forall(Impl i |
2176-
assocFunctionInfoNonBlanket(_, name, arity, selfPos, i, _, strippedTypePath, strippedType) and
2197+
assocFunctionInfoNonBlanket(_, name, arity, _, pos, i, _, strippedTypePath, strippedType) and
21772198
not i.hasTrait()
21782199
|
21792200
this.hasIncompatibleInherentTarget(i)
@@ -2218,6 +2239,7 @@ private module MethodResolution {
22182239
private newtype TMethodCallDerefCand =
22192240
MkMethodCallDerefCand(MethodCall mc, FunctionPosition selfPos, DerefChain derefChain) {
22202241
mc.supportsAutoDerefAndBorrow() and
2242+
selfPos.isSelf() and
22212243
mc.hasNoCompatibleTargetMutBorrow(selfPos, derefChain) and
22222244
exists(mc.getACandidateReceiverTypeAtNoBorrow(selfPos, derefChain, TypePath::nil()))
22232245
}
@@ -2285,9 +2307,9 @@ private module MethodResolution {
22852307
predicate hasBlanketCandidate(
22862308
MethodCallCand mcc, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
22872309
) {
2288-
exists(MethodCall mc, FunctionPosition selfPos, BorrowKind borrow |
2289-
mcc = MkMethodCallCand(mc, selfPos, _, borrow) and
2290-
methodCallBlanketLikeCandidate(mc, _, selfPos, impl, _, blanketPath, blanketTypeParam) and
2310+
exists(MethodCall mc, FunctionPosition pos, BorrowKind borrow |
2311+
mcc = MkMethodCallCand(mc, _, pos, _, borrow) and
2312+
methodCallBlanketLikeCandidate(mc, _, _, pos, impl, _, blanketPath, blanketTypeParam) and
22912313
// Only apply blanket implementations when no other implementations are possible;
22922314
// this is to account for codebases that use the (unstable) specialization feature
22932315
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
@@ -2317,14 +2339,14 @@ private module MethodResolution {
23172339
MethodCallCand mcc, ImplOrTraitItemNode i, AssocFunctionType selfType
23182340
) {
23192341
exists(
2320-
MethodCall mc, FunctionPosition selfPos, Function f, string name, int arity,
2342+
MethodCall mc, FunctionPosition pos, Function f, string name, int arity,
23212343
TypePath strippedTypePath, Type strippedType
23222344
|
2323-
mcc.hasSignature(mc, selfPos, strippedTypePath, strippedType, name, arity)
2345+
mcc.hasSignature(mc, pos, strippedTypePath, strippedType, name, arity)
23242346
|
2325-
methodCallNonBlanketCandidate(mc, f, selfPos, i, selfType, strippedTypePath, strippedType)
2347+
methodCallNonBlanketCandidate(mc, f, _, pos, i, selfType, strippedTypePath, strippedType)
23262348
or
2327-
methodCallBlanketLikeCandidate(mc, f, selfPos, i, selfType, _, _) and
2349+
methodCallBlanketLikeCandidate(mc, f, _, pos, i, selfType, _, _) and
23282350
ReceiverSatisfiesBlanketLikeConstraint::satisfiesBlanketConstraint(mcc, i)
23292351
)
23302352
}
@@ -2361,9 +2383,9 @@ private module MethodResolution {
23612383
predicate potentialInstantiationOf(
23622384
MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint
23632385
) {
2364-
exists(MethodCall mc, FunctionPosition selfPos |
2365-
mcc = MkMethodCallCand(mc, selfPos, _, _) and
2366-
methodCallBlanketLikeCandidate(mc, _, selfPos, abs, constraint, _, _) and
2386+
exists(MethodCall mc, FunctionPosition pos |
2387+
mcc = MkMethodCallCand(mc, _, pos, _, _) and
2388+
methodCallBlanketLikeCandidate(mc, _, _, pos, abs, constraint, _, _) and
23672389
if abs.(Impl).hasTrait()
23682390
then
23692391
// inherent methods take precedence over trait methods, so only allow
@@ -2406,11 +2428,11 @@ private module MethodResolution {
24062428
}
24072429

24082430
class Call extends MethodCallCand {
2409-
Type getArgType(FunctionPosition pos, TypePath path) {
2410-
result = mc_.getArgumentTypeAt(pos.asArgumentPosition(), path)
2431+
Type getArgType(FunctionPosition pos_, TypePath path) {
2432+
result = mc_.getArgumentTypeAt(pos_.asArgumentPosition(), path)
24112433
or
2412-
pos.isReturn() and
2413-
result = inferType(mc_.getNodeAt(pos), path)
2434+
pos_.isReturn() and
2435+
result = inferType(mc_.getNodeAt(pos_), path)
24142436
}
24152437

24162438
predicate hasTargetCand(ImplOrTraitItemNode i, Function f) {
@@ -4227,7 +4249,7 @@ private module Debug {
42274249
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
42284250
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
42294251
filepath.matches("%/main.rs") and
4230-
startline = 103
4252+
startline = 93
42314253
)
42324254
}
42334255

0 commit comments

Comments
 (0)