Skip to content

Commit e56bc06

Browse files
committed
wip4
1 parent d9a2a65 commit e56bc06

File tree

1 file changed

+45
-47
lines changed

1 file changed

+45
-47
lines changed

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

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,8 @@ private module MethodCallResolution {
12381238
derefChain = ""
12391239
or
12401240
exists(TypePath path0, Type t0, string derefChain0 |
1241-
t0 = this.getACandidateReceiverTypeAtNoMatch(path0, derefChain0)
1241+
this.noCandidateReceiverTypeAt(derefChain0) and
1242+
t0 = this.getACandidateReceiverTypeAtNoBorrow(path0, derefChain0)
12421243
|
12431244
path0.isCons(TRefTypeParameter(), path) and
12441245
result = t0 and
@@ -1252,23 +1253,29 @@ private module MethodCallResolution {
12521253
)
12531254
}
12541255

1256+
/**
1257+
* Holds if the method inside `i` with matching name and arity can be ruled out
1258+
* as a candidate for the receiver type represented by `derefChainBorrow`.
1259+
*/
12551260
pragma[nomagic]
12561261
private predicate isNotCandidate(ImplOrTraitItemNode i, string derefChainBorrow) {
12571262
IsInstantiationOf<MethodCallCand, FunctionType, MethodCallIsInstantiationOfInput>::isNotInstantiationOf(MkMethodCallCand(this,
12581263
derefChainBorrow), i, _)
12591264
or
1260-
// not MethodCallIsInstantiationOfInput::potentialInstantiationOf(mcc, abs, constraint)
12611265
exists(Type rootType, TypePath selfRootPath, Type selfRootType |
12621266
rootType = this.getACandidateReceiverTypeAtSubstituteTraitBounds(derefChainBorrow) and
1263-
// mcc.isMethodCall(mc, selfPath, selfType, name, arity) and
12641267
methodCallCandidate(this, i, _, rootType, selfRootPath, selfRootType) and
12651268
selfRootType !=
12661269
this.getACandidateReceiverTypeAtSubstituteTraitBounds(selfRootPath, derefChainBorrow)
12671270
)
12681271
}
12691272

1273+
/**
1274+
* Holds if the candidate receiver type represented by `derefChain` does not
1275+
* have a matching method target.
1276+
*/
12701277
pragma[nomagic]
1271-
private predicate getACandidateReceiverTypeAtNoBorrowNoMatch0(string derefChain) {
1278+
private predicate noCandidateReceiverTypeAtNoBorrow(string derefChain) {
12721279
exists(Type rootType, string derefChainBorrow |
12731280
derefChainBorrow = derefChain + ";" and
12741281
not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
@@ -1280,43 +1287,36 @@ private module MethodCallResolution {
12801287
)
12811288
}
12821289

1283-
pragma[nomagic]
1284-
private Type getACandidateReceiverTypeAtNoBorrowNoMatch(TypePath path, string derefChain) {
1285-
result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
1286-
this.getACandidateReceiverTypeAtNoBorrowNoMatch0(derefChain)
1287-
}
1288-
12891290
pragma[nomagic]
12901291
private predicate hasRefCandidate(ImplOrTraitItemNode i) {
12911292
methodCallCandidate(this, i, _, TRefType(), _, _)
12921293
}
12931294

1295+
/**
1296+
* Holds if the candidate receiver type represented by `derefChain;borrow` does not
1297+
* have a matching method target.
1298+
*/
12941299
pragma[nomagic]
1295-
private predicate getACandidateReceiverTypeAtNoMatch0(string derefChain) {
1300+
private predicate noCandidateReceiverTypeAt(string derefChain) {
12961301
exists(string derefChainBorrow |
12971302
derefChainBorrow = derefChain + ";borrow" and
1298-
this.getACandidateReceiverTypeAtNoBorrowNoMatch0(derefChain)
1303+
this.noCandidateReceiverTypeAtNoBorrow(derefChain)
12991304
|
13001305
forall(ImplOrTraitItemNode i | this.hasRefCandidate(i) |
13011306
this.isNotCandidate(i, derefChainBorrow)
13021307
)
13031308
)
13041309
}
13051310

1306-
pragma[nomagic]
1307-
private Type getACandidateReceiverTypeAtNoMatch(TypePath path, string derefChain) {
1308-
result = this.getACandidateReceiverTypeAtNoBorrowNoMatch(path, derefChain) and
1309-
this.getACandidateReceiverTypeAtNoMatch0(derefChain)
1310-
}
1311-
13121311
/**
13131312
* Gets a [candidate receiver type][1] of this method call at `path`.
13141313
*
13151314
* The type is obtained by repeatedly dereferencing the receiver expression's type,
13161315
* as long as the method cannot be resolved in an earlier candidate type, and possibly
13171316
* applying a borrow at the end.
13181317
*
1319-
* The string `derefChainBorrow` encodes the above, separated by a semi-colon.
1318+
* The string `derefChainBorrow` encodes the sequences of dereferences and whether a
1319+
* borrow has been applied.
13201320
*
13211321
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
13221322
*/
@@ -1326,19 +1326,24 @@ private module MethodCallResolution {
13261326
result = this.getACandidateReceiverTypeAtNoBorrow(path, derefChain) and
13271327
derefChainBorrow = derefChain + ";"
13281328
or
1329-
exists(TypePath path0, Type t0 |
1330-
t0 = this.getACandidateReceiverTypeAtNoBorrowNoMatch(path0, derefChain) and
1331-
derefChainBorrow = derefChain + ";borrow"
1332-
|
1329+
this.noCandidateReceiverTypeAtNoBorrow(derefChain) and
1330+
derefChainBorrow = derefChain + ";borrow" and
1331+
(
13331332
path.isEmpty() and
13341333
result = TRefType()
13351334
or
1336-
path = TypePath::cons(TRefTypeParameter(), path0) and
1337-
result = t0
1335+
exists(TypePath suffix |
1336+
result = this.getACandidateReceiverTypeAtNoBorrow(suffix, derefChain) and
1337+
path = TypePath::cons(TRefTypeParameter(), suffix)
1338+
)
13381339
)
13391340
)
13401341
}
13411342

1343+
/**
1344+
* Same as `getACandidateReceiverTypeAt`, but with traits substituted in for types
1345+
* with trait bounds.
1346+
*/
13421347
pragma[nomagic]
13431348
Type getACandidateReceiverTypeAtSubstituteTraitBounds(TypePath path, string derefChainBorrow) {
13441349
result = substituteTraitBounds(this.getACandidateReceiverTypeAt(path, derefChainBorrow))
@@ -1427,19 +1432,16 @@ private module MethodCallResolution {
14271432
mc.isMethodCall(name, arity)
14281433
}
14291434

1435+
/**
1436+
* Holds if the inherent method inside `i` with matching name and arity can be
1437+
* ruled out as a candidate for this call.
1438+
*/
14301439
pragma[nomagic]
1431-
private predicate isNotInherentTarget(Impl impl) {
1440+
private predicate isNotInherentCandidate(Impl impl) {
14321441
IsInstantiationOf<MethodCallCand, FunctionType, MethodCallIsNotInstantiationOfInput>::isNotInstantiationOf(this,
14331442
impl, _)
14341443
}
14351444

1436-
// pragma[nomagic]
1437-
// private predicate blah(
1438-
// Type type, Impl i, FunctionType self, TypePath selfRootPath, Type selfRootType
1439-
// ) {
1440-
// not i.hasTrait() and
1441-
// mc_.blah(type, i, self, selfPath, selfType, derefChainBorrow)
1442-
// }
14431445
/**
14441446
* Holds if this method call has no inherent target, i.e., it does not
14451447
* resolve to a method in an `impl` block for the type of the receiver.
@@ -1452,14 +1454,7 @@ private module MethodCallResolution {
14521454
methodInfo(_, name, arity, i, self, rootType, selfRootPath, selfRootType) and
14531455
not i.hasTrait()
14541456
|
1455-
// this.blah(type, i, self, selfPath, selfType)
1456-
// or
1457-
this.isNotInherentTarget(i)
1458-
// forall(Impl impl |
1459-
// methodInfo(type, name, arity, impl, _, _, _) and
1460-
// not impl.hasTrait()
1461-
// |
1462-
// this.isNotInherentTarget(impl)
1457+
this.isNotInherentCandidate(i)
14631458
)
14641459
)
14651460
}
@@ -1518,6 +1513,10 @@ private module MethodCallResolution {
15181513
Location getLocation() { result = mc_.getLocation() }
15191514
}
15201515

1516+
/**
1517+
* A configuration for matching the type of a receiver against the type of
1518+
* a `self` parameter.
1519+
*/
15211520
private module MethodCallIsInstantiationOfInput implements
15221521
IsInstantiationOfInputSig<MethodCallCand, FunctionType>
15231522
{
@@ -1528,7 +1527,6 @@ private module MethodCallResolution {
15281527
exists(MethodCall mc, string name, int arity, TypePath selfRootPath, Type selfRootType |
15291528
mcc.isMethodCall(mc, selfRootPath, selfRootType, name, arity) and
15301529
methodCallCandidate(mc, abs, constraint, _, selfRootPath, selfRootType)
1531-
// mc = Debug::getRelevantLocatable()
15321530
)
15331531
}
15341532

@@ -1537,6 +1535,10 @@ private module MethodCallResolution {
15371535
}
15381536
}
15391537

1538+
/**
1539+
* A configuration for anti-matching the type of a receiver against the type of
1540+
* a `self` parameter in an inherent method.
1541+
*/
15401542
private module MethodCallIsNotInstantiationOfInput implements
15411543
IsInstantiationOfInputSig<MethodCallCand, FunctionType>
15421544
{
@@ -1548,7 +1550,6 @@ private module MethodCallResolution {
15481550
exists(MethodCall mc, string name, int arity, Type rootType |
15491551
mcc.isMethodCall(mc, TypePath::nil(), rootType, name, arity) and
15501552
methodCallCandidate(mc, abs, constraint, rootType, _, _)
1551-
// mc = Debug::getRelevantLocatable()
15521553
)
15531554
}
15541555

@@ -1857,8 +1858,7 @@ private module FunctionCallResolution {
18571858
/**
18581859
* Gets the target of this call, where resolution does not rely on type inference.
18591860
*/
1860-
// inline to reduce non-linear recursion
1861-
pragma[inline]
1861+
pragma[nomagic]
18621862
private ItemNode resolveUnambigousFunctionCallTarget() {
18631863
(
18641864
result = this.getATraitCandidateMethod(_, _, _, _)
@@ -1869,8 +1869,6 @@ private module FunctionCallResolution {
18691869
not functionResolutionDependsOnArgument(_, result, _, _, _)
18701870
}
18711871

1872-
// inline to reduce non-linear recursion
1873-
pragma[inline]
18741872
ItemNode resolveCallTarget() {
18751873
result = this.resolveUnambigousFunctionCallTarget()
18761874
or

0 commit comments

Comments
 (0)