Skip to content

Commit 91d996a

Browse files
committed
foo
1 parent 9b0f565 commit 91d996a

File tree

1 file changed

+115
-74
lines changed

1 file changed

+115
-74
lines changed

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

Lines changed: 115 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,114 @@ private Type substituteLookupTraits(Type t) {
11761176
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
11771177
*/
11781178
private module MethodCallResolution {
1179+
/**
1180+
* Provides logic for checking receiver types against constraints of
1181+
* [blanket implementations][1].
1182+
*
1183+
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
1184+
*/
1185+
module BlanketImplementation {
1186+
/**
1187+
* Holds if `tp` is the type parameter of a blanket implementation and
1188+
* `traitBound` is the first non-trivial trait bound of `tp`.
1189+
*/
1190+
pragma[nomagic]
1191+
private predicate blanketImplementationTraitBound(TypeParamItemNode tp, Trait traitBound) {
1192+
tp = any(ImplItemNode impl).getBlanketImplementationTypeParam() and
1193+
traitBound =
1194+
min(Trait trait, int i |
1195+
trait = tp.resolveBound(i) and
1196+
// Exclude traits that are known to not narrow things down very much.
1197+
not trait.getName().getText() =
1198+
[
1199+
"Sized", "Clone",
1200+
// The auto traits
1201+
"Send", "Sync", "Unpin", "UnwindSafe", "RefUnwindSafe"
1202+
]
1203+
|
1204+
trait order by i
1205+
)
1206+
}
1207+
1208+
signature module SatisfiesBlanketConstraintInputSig<HasTypeTreeSig ReceiverType> {
1209+
/**
1210+
* Holds if a method call with receiver type `rt` may potentially target
1211+
* `m`, which is defined in a blanket implementation with type parameter
1212+
* `blanketTypeParam`.
1213+
*
1214+
* `blanketPath` points to the type `blanketTypeParam` inside the type of
1215+
* `m`'s `self` parameter.
1216+
*/
1217+
predicate hasBlanketCandidate(
1218+
ReceiverType rt, Function m, TypePath blanketPath, TypeParam blanketTypeParam
1219+
);
1220+
}
1221+
1222+
module SatisfiesBlanketConstraint<
1223+
HasTypeTreeSig ReceiverType, SatisfiesBlanketConstraintInputSig<ReceiverType> Input>
1224+
{
1225+
private newtype TReceiverTypeAndBlanketOffset =
1226+
MkReceiverTypeAndBlanketOffset(ReceiverType rt, TypePath blanketPath) {
1227+
Input::hasBlanketCandidate(rt, _, blanketPath, _)
1228+
}
1229+
1230+
private class ReceiverTypeAndBlanketOffset extends MkReceiverTypeAndBlanketOffset {
1231+
ReceiverType rt;
1232+
TypePath blanketPath;
1233+
1234+
ReceiverTypeAndBlanketOffset() { this = MkReceiverTypeAndBlanketOffset(rt, blanketPath) }
1235+
1236+
ReceiverType getReceiverType() { result = rt }
1237+
1238+
TypePath getBlanketPath() { result = blanketPath }
1239+
1240+
Location getLocation() { result = rt.getLocation() }
1241+
1242+
Type getTypeAt(TypePath path) { result = rt.getTypeAt(blanketPath.appendInverse(path)) }
1243+
1244+
string toString() {
1245+
result = rt.toString() + " [blanket at " + blanketPath.toString() + "]"
1246+
}
1247+
}
1248+
1249+
private module SatisfiesBlanketConstraintInput implements
1250+
SatisfiesConstraintInputSig<ReceiverTypeAndBlanketOffset>
1251+
{
1252+
pragma[nomagic]
1253+
additional predicate relevantConstraint(
1254+
ReceiverTypeAndBlanketOffset rto, Function m, Trait traitBound
1255+
) {
1256+
exists(ReceiverType rt, TypePath blanketPath, TypeParam blanketTypeParam |
1257+
rto = MkReceiverTypeAndBlanketOffset(rt, blanketPath) and
1258+
Input::hasBlanketCandidate(rt, m, blanketPath, blanketTypeParam) and
1259+
blanketImplementationTraitBound(blanketTypeParam, traitBound)
1260+
)
1261+
}
1262+
1263+
pragma[nomagic]
1264+
predicate relevantConstraint(ReceiverTypeAndBlanketOffset rto, Type constraint) {
1265+
relevantConstraint(rto, _, constraint.(TraitType).getTrait())
1266+
}
1267+
1268+
predicate useUniversalConditions() { none() }
1269+
}
1270+
1271+
/**
1272+
* Holds if the receiver type `rt` satisfies the first non-trivial blanket
1273+
* constraint of the method `m`.
1274+
*/
1275+
pragma[nomagic]
1276+
predicate satisfiesBlanketConstraint(ReceiverType rt, Function m) {
1277+
exists(ReceiverTypeAndBlanketOffset rto, Trait traitBound |
1278+
rto = MkReceiverTypeAndBlanketOffset(rt, _) and
1279+
SatisfiesBlanketConstraintInput::relevantConstraint(rto, m, traitBound) and
1280+
SatisfiesConstraint<ReceiverTypeAndBlanketOffset, SatisfiesBlanketConstraintInput>::satisfiesConstraintType(rto,
1281+
TTrait(traitBound), _, _)
1282+
)
1283+
}
1284+
}
1285+
}
1286+
11791287
/**
11801288
* Holds if `root` is a valid complex [`self` root type][1], with type
11811289
* parameter `tp`.
@@ -1684,86 +1792,18 @@ private module MethodCallResolution {
16841792
Location getLocation() { result = mc_.getLocation() }
16851793
}
16861794

1687-
private newtype TMethodCallCandAndBlanketOffset =
1688-
MkMethodCallCandAndBlanketOffset(MethodCallCand mcc, TypePath blanketPath) {
1689-
exists(MethodCall mc, string name, int arity, TypeParam blanketTypeParam |
1690-
mcc.hasInfo(mc, _, _, name, arity) and
1691-
methodCallBlanketCandidate(mc, _, _, _, blanketPath, blanketTypeParam)
1692-
)
1693-
}
1694-
1695-
private class MethodCallCandAndBlanketOffset extends MkMethodCallCandAndBlanketOffset {
1696-
MethodCallCand mcc_;
1697-
TypePath blanketPath;
1698-
1699-
MethodCallCandAndBlanketOffset() { this = MkMethodCallCandAndBlanketOffset(mcc_, blanketPath) }
1700-
1701-
MethodCallCand getMethodCallCand() { result = mcc_ }
1702-
1703-
TypePath getBlanketPath() { result = blanketPath }
1704-
1705-
Location getLocation() { result = mcc_.getLocation() }
1706-
1707-
Type getTypeAt(TypePath path) { result = mcc_.getTypeAt(blanketPath.appendInverse(path)) }
1708-
1709-
string toString() { result = mcc_.toString() + " (blanket at " + blanketPath.toString() + ")" }
1710-
}
1711-
17121795
private module SatisfiesBlanketConstraintInput implements
1713-
SatisfiesConstraintInputSig<MethodCallCandAndBlanketOffset>
1796+
BlanketImplementation::SatisfiesBlanketConstraintInputSig<MethodCallCand>
17141797
{
1715-
/**
1716-
* Holds if `impl` is a blanket implementation for a type parameter and
1717-
* `traitBound` is the first non-trivial trait bound of that type parameter.
1718-
*/
17191798
pragma[nomagic]
1720-
private predicate blanketImplementationTraitBound(TypeParamItemNode tp, Trait traitBound) {
1721-
tp = any(ImplItemNode impl).getBlanketImplementationTypeParam() and
1722-
traitBound =
1723-
min(Trait trait, int i |
1724-
trait = tp.resolveBound(i) and
1725-
// Exclude traits that are known to not narrow things down very much.
1726-
not trait.getName().getText() =
1727-
[
1728-
"Sized", "Clone",
1729-
// The auto traits
1730-
"Send", "Sync", "Unpin", "UnwindSafe", "RefUnwindSafe"
1731-
]
1732-
|
1733-
trait order by i
1734-
)
1735-
}
1736-
1737-
pragma[nomagic]
1738-
additional predicate relevantConstraint(
1739-
MethodCallCandAndBlanketOffset mcco, Function m, Trait traitBound
1799+
predicate hasBlanketCandidate(
1800+
MethodCallCand mcc, Function m, TypePath blanketPath, TypeParam blanketTypeParam
17401801
) {
1741-
exists(
1742-
MethodCallCand mcc, MethodCall mc, string name, int arity, TypePath blanketPath,
1743-
TypeParam blanketTypeParam
1744-
|
1745-
mcco = MkMethodCallCandAndBlanketOffset(mcc, blanketPath) and
1802+
exists(MethodCall mc, string name, int arity |
17461803
mcc.hasInfo(mc, _, _, name, arity) and
1747-
methodCallBlanketCandidate(mc, m, _, _, blanketPath, blanketTypeParam) and
1748-
blanketImplementationTraitBound(blanketTypeParam, traitBound)
1804+
methodCallBlanketCandidate(mc, m, _, _, blanketPath, blanketTypeParam)
17491805
)
17501806
}
1751-
1752-
pragma[nomagic]
1753-
predicate relevantConstraint(MethodCallCandAndBlanketOffset mcco, Type constraint) {
1754-
relevantConstraint(mcco, _, constraint.(TraitType).getTrait())
1755-
}
1756-
1757-
predicate useUniversalConditions() { none() }
1758-
}
1759-
1760-
private predicate hasBlanketImpl(MethodCallCand mcc, Function f) {
1761-
exists(MethodCallCandAndBlanketOffset mcco, Trait traitBound |
1762-
mcco = MkMethodCallCandAndBlanketOffset(mcc, _) and
1763-
SatisfiesBlanketConstraintInput::relevantConstraint(mcco, f, traitBound) and
1764-
SatisfiesConstraint<MethodCallCandAndBlanketOffset, SatisfiesBlanketConstraintInput>::satisfiesConstraintType(mcco,
1765-
TTrait(traitBound), _, _)
1766-
)
17671807
}
17681808

17691809
/**
@@ -1786,7 +1826,8 @@ private module MethodCallResolution {
17861826
methodCallNonBlanketCandidate(mc, m, abs, constraint, strippedTypePath, strippedType)
17871827
or
17881828
methodCallBlanketCandidate(mc, m, abs, constraint, _, _) and
1789-
hasBlanketImpl(mcc, m)
1829+
BlanketImplementation::SatisfiesBlanketConstraint<MethodCallCand, SatisfiesBlanketConstraintInput>::satisfiesBlanketConstraint(mcc,
1830+
m)
17901831
)
17911832
}
17921833

0 commit comments

Comments
 (0)