Skip to content

Commit d11b22b

Browse files
committed
wip2
1 parent 195a708 commit d11b22b

File tree

3 files changed

+115
-131
lines changed

3 files changed

+115
-131
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,16 @@ module TraitIsVisible<relevantTraitVisibleSig/2 relevantTraitVisible> {
14461446
predicate traitIsVisible(Element element, Trait trait) {
14471447
exists(ItemNode encl | traitLookup(encl, element, trait) and trait = encl.getASuccessor(_, _))
14481448
}
1449+
1450+
/** Holds if the trait `trait` is _not_ visible at `element`. */
1451+
pragma[nomagic]
1452+
predicate traitIsNotVisible(Element element, Trait trait) {
1453+
exists(ItemNode top |
1454+
traitLookup(top, element, trait) and
1455+
not exists(getOuterScope(top)) and
1456+
not trait = top.getASuccessor(_, _)
1457+
)
1458+
}
14491459
}
14501460

14511461
pragma[nomagic]

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

Lines changed: 78 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,33 @@ private module MethodCallResolution {
11721172
this.isMethodCall(name, arity)
11731173
}
11741174

1175+
pragma[nomagic]
1176+
predicate hasTraitImplCandidate(
1177+
ImplItemNode i, FunctionPositionType self, string derefChainBorrow, Trait trait
1178+
) {
1179+
exists(Type rootType, string name, int arity |
1180+
this.isMethodCall0(rootType, name, arity, derefChainBorrow) and
1181+
methodCandidate(rootType, name, arity, i, self) and
1182+
trait = i.resolveTraitTy()
1183+
)
1184+
}
1185+
1186+
pragma[nomagic]
1187+
private predicate isNotCandidate(
1188+
ImplOrTraitItemNode i, FunctionPositionType self, string derefChainBorrow
1189+
) {
1190+
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(MkMethodCallCand(this,
1191+
derefChainBorrow), i, self)
1192+
or
1193+
exists(Trait trait |
1194+
this.hasTraitImplCandidate(i, self, derefChainBorrow, trait) and
1195+
TraitIsVisible<relevantTraitVisible1/2>::traitIsNotVisible(this, trait)
1196+
|
1197+
not this instanceof IndexExpr or
1198+
not trait instanceof IndexTrait
1199+
)
1200+
}
1201+
11751202
pragma[nomagic]
11761203
private Type getACandidateReceiverTypeAtNoBorrowNoMatch(TypePath path, string derefChain) {
11771204
result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
@@ -1180,11 +1207,10 @@ private module MethodCallResolution {
11801207
not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
11811208
this.isMethodCall0(rootType, name, arity, derefChainBorrow)
11821209
|
1183-
forall(Impl impl, FunctionPositionType self |
1184-
methodCandidate(rootType, name, arity, impl, self)
1210+
forall(ImplOrTraitItemNode i, FunctionPositionType self |
1211+
methodCandidate(rootType, name, arity, i, self)
11851212
|
1186-
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(MkMethodCallCand(this,
1187-
derefChainBorrow), impl, self)
1213+
this.isNotCandidate(i, self, derefChainBorrow)
11881214
)
11891215
)
11901216
}
@@ -1196,11 +1222,10 @@ private module MethodCallResolution {
11961222
derefChainBorrow = derefChain + ";borrow" and
11971223
this.isMethodCall0(rootType, name, arity, derefChainBorrow)
11981224
|
1199-
forall(Impl impl, FunctionPositionType self |
1200-
methodCandidate(rootType, name, arity, impl, self)
1225+
forall(ImplOrTraitItemNode i, FunctionPositionType self |
1226+
methodCandidate(rootType, name, arity, i, self)
12011227
|
1202-
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(MkMethodCallCand(this,
1203-
derefChainBorrow), impl, self)
1228+
this.isNotCandidate(i, self, derefChainBorrow)
12041229
)
12051230
)
12061231
}
@@ -1256,6 +1281,10 @@ private module MethodCallResolution {
12561281
}
12571282
}
12581283

1284+
private predicate relevantTraitVisible1(Element mc, Trait trait) {
1285+
mc.(MethodCall).hasTraitImplCandidate(_, _, _, trait)
1286+
}
1287+
12591288
private class MethodCallMethodCallExpr extends MethodCall, MethodCallExpr {
12601289
pragma[nomagic]
12611290
override predicate isMethodCall(string name, int arity) {
@@ -1316,6 +1345,13 @@ private module MethodCallResolution {
13161345
mc.isMethodCall(name, arity)
13171346
}
13181347

1348+
pragma[nomagic]
1349+
private predicate isNotInherentTarget(Impl impl) {
1350+
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(this,
1351+
impl, _) and
1352+
not impl.hasTrait()
1353+
}
1354+
13191355
/**
13201356
* Holds if this method call has no inherent target, i.e., it does not
13211357
* resolve to a method in an `impl` block for the type of the receiver.
@@ -1328,8 +1364,7 @@ private module MethodCallResolution {
13281364
methodCandidate(rootType, name, arity, impl, _) and
13291365
not impl.hasTrait()
13301366
|
1331-
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(this,
1332-
impl, _)
1367+
this.isNotInherentTarget(impl)
13331368
)
13341369
)
13351370
}
@@ -1374,35 +1409,32 @@ private module MethodCallResolution {
13741409
{
13751410
pragma[nomagic]
13761411
private predicate methodCallCandidate(
1377-
MethodCallCand mc, ImplOrTraitItemNode i, FunctionPositionType constraint
1412+
MethodCallCand mcc, MethodCall mc, ImplOrTraitItemNode i, FunctionPositionType constraint
13781413
) {
13791414
exists(Type rootType, string name, int arity |
1380-
mc.isMethodCall(rootType, name, arity) and
1381-
methodCandidate(rootType, name, arity, i, constraint)
1415+
mcc.isMethodCall(rootType, name, arity) and
1416+
methodCandidate(rootType, name, arity, i, constraint) and
1417+
mc = mcc.getMethodCall()
13821418
)
13831419
}
13841420

13851421
private predicate relevantTraitVisible(Element mc, Trait trait) {
1386-
trait =
1387-
any(ImplItemNode impl | methodCallCandidate(MkMethodCallCand(mc, _), impl, _))
1388-
.resolveTraitTy()
1422+
trait = any(ImplItemNode impl | methodCallCandidate(_, mc, impl, _)).resolveTraitTy()
13891423
}
13901424

13911425
pragma[nomagic]
13921426
predicate potentialInstantiationOf(
1393-
MethodCallCand mc, TypeAbstraction abs, FunctionPositionType constraint
1427+
MethodCallCand mcc, TypeAbstraction abs, FunctionPositionType constraint
13941428
) {
1395-
methodCallCandidate(mc, abs, constraint) and
1396-
(
1429+
exists(MethodCall mc | methodCallCandidate(mcc, mc, abs, constraint) |
13971430
not exists(abs.(ImplItemNode).resolveTraitTy())
13981431
or
13991432
// If the `impl` block implements a trait, that trait must be visible in
14001433
// order for the `impl` to be valid.
14011434
exists(Trait trait | pragma[only_bind_into](trait) = abs.(ImplItemNode).resolveTraitTy() |
1402-
TraitIsVisible<relevantTraitVisible/2>::traitIsVisible(mc.getMethodCall(),
1403-
pragma[only_bind_into](trait))
1435+
TraitIsVisible<relevantTraitVisible/2>::traitIsVisible(mc, pragma[only_bind_into](trait))
14041436
or
1405-
mc.getMethodCall() instanceof IndexExpr and
1437+
mc instanceof IndexExpr and
14061438
trait instanceof IndexTrait
14071439
)
14081440
)
@@ -1527,12 +1559,13 @@ private module MethodCallMatchingInput implements MatchingWithStateInputSig {
15271559
)
15281560
}
15291561

1530-
bindingset[state]
1562+
pragma[nomagic]
15311563
Type getInferredType(State state, AccessPosition apos, TypePath path) {
15321564
apos.asArgumentPosition().isSelf() and
15331565
result = this.getInferredSelfType(state, path)
15341566
or
1535-
result = this.getInferredNonSelfType(apos, path)
1567+
result = this.getInferredNonSelfType(apos, path) and
1568+
exists(this.getTarget(state))
15361569
}
15371570

15381571
Declaration getTarget(State state) {
@@ -2000,10 +2033,11 @@ private module OperationResolution {
20002033
}
20012034

20022035
pragma[nomagic]
2003-
predicate isOperation(Type rootType, string name, int arity) {
2036+
predicate isOperation(Type rootType, Trait trait, string name, int arity) {
20042037
name = this.(Call).getMethodName() and
20052038
arity = this.(Call).getNumberOfArguments() and
2006-
rootType = this.getTypeAt(TypePath::nil())
2039+
rootType = this.getTypeAt(TypePath::nil()) and
2040+
trait = this.(Call).getTrait()
20072041
}
20082042

20092043
pragma[nomagic]
@@ -2055,9 +2089,13 @@ private module OperationResolution {
20552089

20562090
pragma[nomagic]
20572091
predicate potentialInstantiationOf(Op op, TypeAbstraction abs, FunctionPositionType constraint) {
2058-
exists(Type rootType, string name, int arity |
2059-
op.isOperation(rootType, name, arity) and
2060-
methodCandidateTrait(rootType, op.(Call).getTrait(), name, arity, abs, constraint)
2092+
exists(Type rootType, Trait trait, string name, int arity |
2093+
op.isOperation(rootType, trait, name, arity) and
2094+
MethodCallResolution::methodCandidate(rootType, name, arity, abs, constraint)
2095+
|
2096+
trait = abs.(ImplItemNode).resolveTraitTy()
2097+
or
2098+
trait = abs
20612099
)
20622100
}
20632101

@@ -2330,7 +2368,17 @@ private module FieldExprMatchingInput implements MatchingInputSig {
23302368
}
23312369

23322370
Type getInferredType(AccessPosition apos, TypePath path) {
2333-
result = inferType(this.getNodeAt(apos), path)
2371+
exists(TypePath path0 | result = inferType(this.getNodeAt(apos), path0) |
2372+
if apos.isSelf()
2373+
then
2374+
// adjust for implicit deref
2375+
path0.isCons(TRefTypeParameter(), path)
2376+
or
2377+
not path0.isCons(TRefTypeParameter(), _) and
2378+
not (result = TRefType() and path0.isEmpty()) and
2379+
path = path0
2380+
else path = path0
2381+
)
23342382
}
23352383

23362384
Declaration getTarget() {
@@ -2347,28 +2395,6 @@ private module FieldExprMatchingInput implements MatchingInputSig {
23472395
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) {
23482396
apos = dpos
23492397
}
2350-
2351-
bindingset[apos, target, path, t]
2352-
pragma[inline_late]
2353-
predicate adjustAccessType(
2354-
AccessPosition apos, Declaration target, TypePath path, Type t, TypePath pathAdj, Type tAdj
2355-
) {
2356-
exists(target) and
2357-
if apos.isSelf()
2358-
then
2359-
// adjust for implicit deref
2360-
path.isCons(TRefTypeParameter(), pathAdj) and
2361-
tAdj = t
2362-
or
2363-
not path.isCons(TRefTypeParameter(), _) and
2364-
not (t = TRefType() and path.isEmpty()) and
2365-
pathAdj = path and
2366-
tAdj = t
2367-
else (
2368-
pathAdj = path and
2369-
tAdj = t
2370-
)
2371-
}
23722398
}
23732399

23742400
private module FieldExprMatching = Matching<FieldExprMatchingInput>;

0 commit comments

Comments
 (0)