Skip to content

Commit 4030e2c

Browse files
committed
wip4
1 parent 24a7cf7 commit 4030e2c

1 file changed

Lines changed: 121 additions & 33 deletions

File tree

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

Lines changed: 121 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,8 +1162,7 @@ private module MethodCallResolution {
11621162
mc.isMethodCall(name, arity) and
11631163
methodCandidate(type, name, arity, i, self, selfPath, selfType)
11641164
|
1165-
// not CertainTypeInference::inferCertainType(mc.getReceiver(), TypePath::nil()) != type
1166-
not exists(i.(ImplItemNode).resolveTraitTy())
1165+
not i.(Impl).hasTrait()
11671166
or
11681167
methodCallVisibleImplTraitCandidate(mc, i)
11691168
or
@@ -1172,6 +1171,18 @@ private module MethodCallResolution {
11721171
)
11731172
}
11741173

1174+
private class RawImplOrTrait = @impl or @trait;
1175+
1176+
private import codeql.rust.elements.internal.generated.Synth
1177+
1178+
private predicate id(RawImplOrTrait x, RawImplOrTrait y) { x = y }
1179+
1180+
private predicate idOfRaw(RawImplOrTrait x, int y) = equivalenceRelation(id/2)(x, y)
1181+
1182+
private int idOfImplOrTraitItemNode(AstNode node) {
1183+
idOfRaw(Synth::convertAstNodeToRaw(node), result)
1184+
}
1185+
11751186
/**
11761187
* A method call.
11771188
*
@@ -1227,30 +1238,53 @@ private module MethodCallResolution {
12271238

12281239
pragma[nomagic]
12291240
private predicate isMethodCall0(Type type, string name, int arity, string derefChainBorrow) {
1230-
type = this.getACandidateReceiverTypeAt(TypePath::nil(), derefChainBorrow) and
1231-
this.isMethodCall(name, arity)
1241+
exists(Type t |
1242+
t = this.getACandidateReceiverTypeAt(TypePath::nil(), derefChainBorrow) and
1243+
this.isMethodCall(name, arity)
1244+
|
1245+
not exists(getATraitBound(t)) and
1246+
type = t
1247+
or
1248+
type = TTrait(getATraitBound(t))
1249+
)
12321250
}
12331251

12341252
pragma[nomagic]
12351253
private predicate isNotCandidate(
12361254
ImplOrTraitItemNode i, FunctionPositionType self, string derefChainBorrow
12371255
) {
1238-
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(MkMethodCallCand(this,
1256+
IsInstantiationOf<MethodCallCand, FunctionPositionType, MethodCallIsInstantiationOfInput2>::isNotInstantiationOf(MkMethodCallCand(this,
12391257
derefChainBorrow), i, self)
12401258
}
12411259

1260+
// pragma[nomagic]
1261+
// predicate blah(
1262+
// Type type, ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType,
1263+
// string derefChainBorrow
1264+
// ) {
1265+
// selfType != this.getACandidateReceiverTypeAt(selfPath, derefChainBorrow) and
1266+
// methodCallCandidate(this, type, i, self, selfPath, selfType)
1267+
// }
1268+
// idOfImplOrTraitItemNode
1269+
// pragma[nomagic]
1270+
// private ImplOrTraitItemNode getARankedCandidate(TypePath path, string derefChain) {
1271+
// result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
1272+
// exists(Type type, string name, int arity, string derefChainBorrow |
1273+
// derefChainBorrow = derefChain + ";" and
1274+
// not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
1275+
// this.isMethodCall0(type, name, arity, derefChainBorrow)
1276+
// |
1277+
// forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1278+
// methodCallCandidate(this, type, i, self, selfPath, selfType)
1279+
// |
1280+
// this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1281+
// or
1282+
// this.isNotCandidate(i, self, derefChainBorrow)
1283+
// )
1284+
// )
1285+
// }
12421286
pragma[nomagic]
1243-
predicate blah(
1244-
Type type, ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType,
1245-
string derefChainBorrow
1246-
) {
1247-
selfType != this.getACandidateReceiverTypeAt(selfPath, derefChainBorrow) and
1248-
methodCallCandidate(this, type, i, self, selfPath, selfType)
1249-
}
1250-
1251-
pragma[nomagic]
1252-
private Type getACandidateReceiverTypeAtNoBorrowNoMatch(TypePath path, string derefChain) {
1253-
result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
1287+
private predicate getACandidateReceiverTypeAtNoBorrowNoMatch0(string derefChain) {
12541288
exists(Type type, string name, int arity, string derefChainBorrow |
12551289
derefChainBorrow = derefChain + ";" and
12561290
not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
@@ -1259,30 +1293,66 @@ private module MethodCallResolution {
12591293
forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
12601294
methodCallCandidate(this, type, i, self, selfPath, selfType)
12611295
|
1262-
this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1263-
or
1296+
// this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1297+
// or
12641298
this.isNotCandidate(i, self, derefChainBorrow)
12651299
)
12661300
)
12671301
}
12681302

12691303
pragma[nomagic]
1270-
private Type getACandidateReceiverTypeAtNoMatch(TypePath path, string derefChain) {
1271-
result = this.getACandidateReceiverTypeAtNoBorrowNoMatch(path, derefChain) and
1304+
private Type getACandidateReceiverTypeAtNoBorrowNoMatch(TypePath path, string derefChain) {
1305+
result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
1306+
this.getACandidateReceiverTypeAtNoBorrowNoMatch0(derefChain)
1307+
// exists(Type type, string name, int arity, string derefChainBorrow |
1308+
// derefChainBorrow = derefChain + ";" and
1309+
// not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
1310+
// this.isMethodCall0(type, name, arity, derefChainBorrow)
1311+
// |
1312+
// forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1313+
// methodCallCandidate(this, type, i, self, selfPath, selfType)
1314+
// |
1315+
// this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1316+
// or
1317+
// this.isNotCandidate(i, self, derefChainBorrow)
1318+
// )
1319+
// )
1320+
}
1321+
1322+
pragma[nomagic]
1323+
private predicate getACandidateReceiverTypeAtNoMatch0(string derefChain) {
12721324
exists(Type type, string name, int arity, string derefChainBorrow |
12731325
derefChainBorrow = derefChain + ";borrow" and
12741326
this.isMethodCall0(type, name, arity, derefChainBorrow)
12751327
|
12761328
forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
12771329
methodCallCandidate(this, type, i, self, selfPath, selfType)
12781330
|
1279-
this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1280-
or
1331+
// this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1332+
// or
12811333
this.isNotCandidate(i, self, derefChainBorrow)
12821334
)
12831335
)
12841336
}
12851337

1338+
pragma[nomagic]
1339+
private Type getACandidateReceiverTypeAtNoMatch(TypePath path, string derefChain) {
1340+
result = this.getACandidateReceiverTypeAtNoBorrowNoMatch(path, derefChain) and
1341+
this.getACandidateReceiverTypeAtNoMatch0(derefChain)
1342+
// exists(Type type, string name, int arity, string derefChainBorrow |
1343+
// derefChainBorrow = derefChain + ";borrow" and
1344+
// this.isMethodCall0(type, name, arity, derefChainBorrow)
1345+
// |
1346+
// forall(ImplOrTraitItemNode i, FunctionPositionType self, TypePath selfPath, Type selfType |
1347+
// methodCallCandidate(this, type, i, self, selfPath, selfType)
1348+
// |
1349+
// this.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1350+
// or
1351+
// this.isNotCandidate(i, self, derefChainBorrow)
1352+
// )
1353+
// )
1354+
}
1355+
12861356
/**
12871357
* Gets a [candidate receiver type][1] of this method call at `path`.
12881358
*
@@ -1401,14 +1471,13 @@ private module MethodCallResolution {
14011471
impl, _)
14021472
}
14031473

1404-
pragma[nomagic]
1405-
private predicate blah(
1406-
Type type, Impl i, FunctionPositionType self, TypePath selfPath, Type selfType
1407-
) {
1408-
not i.hasTrait() and
1409-
mc_.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1410-
}
1411-
1474+
// pragma[nomagic]
1475+
// private predicate blah(
1476+
// Type type, Impl i, FunctionPositionType self, TypePath selfPath, Type selfType
1477+
// ) {
1478+
// not i.hasTrait() and
1479+
// mc_.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1480+
// }
14121481
/**
14131482
* Holds if this method call has no inherent target, i.e., it does not
14141483
* resolve to a method in an `impl` block for the type of the receiver.
@@ -1421,8 +1490,8 @@ private module MethodCallResolution {
14211490
methodCandidate(type, name, arity, i, self, selfPath, selfType) and
14221491
not i.hasTrait()
14231492
|
1424-
this.blah(type, i, self, selfPath, selfType)
1425-
or
1493+
// this.blah(type, i, self, selfPath, selfType)
1494+
// or
14261495
this.isNotInherentTarget(i)
14271496
// forall(Impl impl |
14281497
// methodCandidate(type, name, arity, impl, _, _, _) and
@@ -1502,14 +1571,33 @@ private module MethodCallResolution {
15021571
}
15031572
}
15041573

1574+
private module MethodCallIsInstantiationOfInput2 implements
1575+
IsInstantiationOfInputSig<MethodCallCand, FunctionPositionType>
1576+
{
1577+
pragma[nomagic]
1578+
predicate potentialInstantiationOf(
1579+
MethodCallCand mcc, TypeAbstraction abs, FunctionPositionType constraint
1580+
) {
1581+
exists(MethodCall mc, string name, int arity, Type rootType |
1582+
mcc.isMethodCall(mc, TypePath::nil(), rootType, name, arity) and
1583+
methodCallCandidate(mc, rootType, abs, constraint, _, _)
1584+
// mc = Debug::getRelevantLocatable()
1585+
)
1586+
}
1587+
1588+
predicate relevantTypeMention(FunctionPositionType constraint) {
1589+
methodCallCandidate(_, _, _, constraint, _, _)
1590+
}
1591+
}
1592+
15051593
private module MethodCallIsNotInstantiationOfInput implements
15061594
IsInstantiationOfInputSig<MethodCallCand, FunctionPositionType>
15071595
{
15081596
pragma[nomagic]
15091597
predicate potentialInstantiationOf(
15101598
MethodCallCand mcc, TypeAbstraction abs, FunctionPositionType constraint
15111599
) {
1512-
MethodCallIsInstantiationOfInput::potentialInstantiationOf(mcc, abs, constraint) and
1600+
MethodCallIsInstantiationOfInput2::potentialInstantiationOf(mcc, abs, constraint) and
15131601
abs = any(Impl i | not i.hasTrait())
15141602
}
15151603

0 commit comments

Comments
 (0)