Skip to content

Commit 90e840e

Browse files
committed
wip3
1 parent 223066a commit 90e840e

File tree

1 file changed

+92
-108
lines changed

1 file changed

+92
-108
lines changed

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

Lines changed: 92 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -891,108 +891,6 @@ private module FunctionOverloading {
891891
}
892892
}
893893

894-
/**
895-
* Provides logic for checking receiver types against constraints of
896-
* [blanket implementations][1].
897-
*
898-
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
899-
*/
900-
private module BlanketImplementation {
901-
/**
902-
* Holds if `tp` is the type parameter of a blanket implementation and
903-
* `traitBound` is the first non-trivial trait bound of `tp`.
904-
*/
905-
pragma[nomagic]
906-
private predicate blanketImplementationTraitBound(TypeParamItemNode tp, Trait traitBound) {
907-
tp = any(ImplItemNode impl).getBlanketImplementationTypeParam() and
908-
traitBound =
909-
min(Trait trait, int i |
910-
trait = tp.resolveBound(i) and
911-
// Exclude traits that are known to not narrow things down very much.
912-
not trait.getName().getText() =
913-
[
914-
"Sized", "Clone",
915-
// The auto traits
916-
"Send", "Sync", "Unpin", "UnwindSafe", "RefUnwindSafe"
917-
]
918-
|
919-
trait order by i
920-
)
921-
}
922-
923-
signature module SatisfiesBlanketConstraintInputSig<HasTypeTreeSig ReceiverType> {
924-
/**
925-
* Holds if a method call with receiver type `rt` may potentially target
926-
* `m`, which is defined in a blanket implementation with type parameter
927-
* `blanketTypeParam`.
928-
*
929-
* `blanketPath` points to the type `blanketTypeParam` inside the type of
930-
* `m`'s `self` parameter.
931-
*/
932-
predicate hasBlanketCandidate(
933-
ReceiverType rt, Function m, TypePath blanketPath, TypeParam blanketTypeParam
934-
);
935-
}
936-
937-
module SatisfiesBlanketConstraint<
938-
HasTypeTreeSig ReceiverType, SatisfiesBlanketConstraintInputSig<ReceiverType> Input>
939-
{
940-
private newtype TReceiverTypeAndBlanketOffset =
941-
MkReceiverTypeAndBlanketOffset(ReceiverType rt, TypePath blanketPath) {
942-
Input::hasBlanketCandidate(rt, _, blanketPath, _)
943-
}
944-
945-
private class ReceiverTypeAndBlanketOffset extends MkReceiverTypeAndBlanketOffset {
946-
ReceiverType rt;
947-
TypePath blanketPath;
948-
949-
ReceiverTypeAndBlanketOffset() { this = MkReceiverTypeAndBlanketOffset(rt, blanketPath) }
950-
951-
Location getLocation() { result = rt.getLocation() }
952-
953-
Type getTypeAt(TypePath path) { result = rt.getTypeAt(blanketPath.appendInverse(path)) }
954-
955-
string toString() { result = rt.toString() + " [blanket at " + blanketPath.toString() + "]" }
956-
}
957-
958-
private module SatisfiesBlanketConstraintInput implements
959-
SatisfiesConstraintInputSig<ReceiverTypeAndBlanketOffset>
960-
{
961-
pragma[nomagic]
962-
additional predicate relevantConstraint(
963-
ReceiverTypeAndBlanketOffset rto, Function m, Trait traitBound
964-
) {
965-
exists(ReceiverType rt, TypePath blanketPath, TypeParam blanketTypeParam |
966-
rto = MkReceiverTypeAndBlanketOffset(rt, blanketPath) and
967-
Input::hasBlanketCandidate(rt, m, blanketPath, blanketTypeParam) and
968-
blanketImplementationTraitBound(blanketTypeParam, traitBound)
969-
)
970-
}
971-
972-
pragma[nomagic]
973-
predicate relevantConstraint(ReceiverTypeAndBlanketOffset rto, Type constraint) {
974-
relevantConstraint(rto, _, constraint.(TraitType).getTrait())
975-
}
976-
977-
predicate useUniversalConditions() { none() }
978-
}
979-
980-
/**
981-
* Holds if the receiver type `rt` satisfies the first non-trivial blanket
982-
* constraint of the method `m`.
983-
*/
984-
pragma[nomagic]
985-
predicate satisfiesBlanketConstraint(ReceiverType rt, Function m) {
986-
exists(ReceiverTypeAndBlanketOffset rto, Trait traitBound |
987-
rto = MkReceiverTypeAndBlanketOffset(rt, _) and
988-
SatisfiesBlanketConstraintInput::relevantConstraint(rto, m, traitBound) and
989-
SatisfiesConstraint<ReceiverTypeAndBlanketOffset, SatisfiesBlanketConstraintInput>::satisfiesConstraintType(rto,
990-
TTrait(traitBound), _, _)
991-
)
992-
}
993-
}
994-
}
995-
996894
private Trait getALookupTrait(Type t) {
997895
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
998896
or
@@ -1657,18 +1555,105 @@ private module MethodCallResolution {
16571555
Location getLocation() { result = mc_.getLocation() }
16581556
}
16591557

1660-
private module SatisfiesBlanketConstraintInput implements
1661-
BlanketImplementation::SatisfiesBlanketConstraintInputSig<MethodCallCand>
1662-
{
1558+
/**
1559+
* Provides logic for checking receiver types against constraints of
1560+
* [blanket implementations][1].
1561+
*
1562+
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
1563+
*/
1564+
private module BlanketImplementation {
1565+
/**
1566+
* Holds if `tp` is the type parameter of a blanket implementation and
1567+
* `traitBound` is the first non-trivial trait bound of `tp`.
1568+
*/
16631569
pragma[nomagic]
1664-
predicate hasBlanketCandidate(
1570+
private predicate blanketImplementationTraitBound(TypeParamItemNode tp, Trait traitBound) {
1571+
tp = any(ImplItemNode impl).getBlanketImplementationTypeParam() and
1572+
traitBound =
1573+
min(Trait trait, int i |
1574+
trait = tp.resolveBound(i) and
1575+
// Exclude traits that are known to not narrow things down very much.
1576+
not trait.getName().getText() =
1577+
[
1578+
"Sized", "Clone",
1579+
// The auto traits
1580+
"Send", "Sync", "Unpin", "UnwindSafe", "RefUnwindSafe"
1581+
]
1582+
|
1583+
trait order by i
1584+
)
1585+
}
1586+
1587+
/**
1588+
* Holds if `mcc` may potentially target `m`, which is defined in a blanket
1589+
* implementation with type parameter `blanketTypeParam`.
1590+
*
1591+
* `blanketPath` points to the type `blanketTypeParam` inside the type of
1592+
* `m`'s `self` parameter.
1593+
*/
1594+
pragma[nomagic]
1595+
private predicate hasBlanketCandidate(
16651596
MethodCallCand mcc, Function m, TypePath blanketPath, TypeParam blanketTypeParam
16661597
) {
16671598
exists(MethodCall mc, string name, int arity |
16681599
mcc.hasSignature(mc, _, _, name, arity) and
16691600
methodCallBlanketCandidate(mc, m, _, _, blanketPath, blanketTypeParam)
16701601
)
16711602
}
1603+
1604+
private newtype TMethodCallCandAndBlanketOffset =
1605+
MkMethodCallCandAndBlanketOffset(MethodCallCand mcc, TypePath blanketPath) {
1606+
hasBlanketCandidate(mcc, _, blanketPath, _)
1607+
}
1608+
1609+
private class MethodCallCandAndBlanketOffset extends MkMethodCallCandAndBlanketOffset {
1610+
MethodCallCand mcc;
1611+
TypePath blanketPath;
1612+
1613+
MethodCallCandAndBlanketOffset() { this = MkMethodCallCandAndBlanketOffset(mcc, blanketPath) }
1614+
1615+
Location getLocation() { result = mcc.getLocation() }
1616+
1617+
Type getTypeAt(TypePath path) { result = mcc.getTypeAt(blanketPath.appendInverse(path)) }
1618+
1619+
string toString() { result = mcc.toString() + " [blanket at " + blanketPath.toString() + "]" }
1620+
}
1621+
1622+
private module SatisfiesBlanketConstraintInput implements
1623+
SatisfiesConstraintInputSig<MethodCallCandAndBlanketOffset>
1624+
{
1625+
pragma[nomagic]
1626+
additional predicate relevantConstraint(
1627+
MethodCallCandAndBlanketOffset mccbo, Function m, Trait traitBound
1628+
) {
1629+
exists(MethodCallCand mcc, TypePath blanketPath, TypeParam blanketTypeParam |
1630+
mccbo = MkMethodCallCandAndBlanketOffset(mcc, blanketPath) and
1631+
hasBlanketCandidate(mcc, m, blanketPath, blanketTypeParam) and
1632+
blanketImplementationTraitBound(blanketTypeParam, traitBound)
1633+
)
1634+
}
1635+
1636+
pragma[nomagic]
1637+
predicate relevantConstraint(MethodCallCandAndBlanketOffset mccbo, Type constraint) {
1638+
relevantConstraint(mccbo, _, constraint.(TraitType).getTrait())
1639+
}
1640+
1641+
predicate useUniversalConditions() { none() }
1642+
}
1643+
1644+
/**
1645+
* Holds if the receiver type of `mcc` satisfies the first non-trivial blanket
1646+
* constraint of the method `m`.
1647+
*/
1648+
pragma[nomagic]
1649+
predicate satisfiesBlanketConstraint(MethodCallCand mcc, Function m) {
1650+
exists(MethodCallCandAndBlanketOffset mccbo, Trait traitBound |
1651+
mccbo = MkMethodCallCandAndBlanketOffset(mcc, _) and
1652+
SatisfiesBlanketConstraintInput::relevantConstraint(mccbo, m, traitBound) and
1653+
SatisfiesConstraint<MethodCallCandAndBlanketOffset, SatisfiesBlanketConstraintInput>::satisfiesConstraintType(mccbo,
1654+
TTrait(traitBound), _, _)
1655+
)
1656+
}
16721657
}
16731658

16741659
/**
@@ -1691,8 +1676,7 @@ private module MethodCallResolution {
16911676
methodCallNonBlanketCandidate(mc, m, abs, constraint, strippedTypePath, strippedType)
16921677
or
16931678
methodCallBlanketCandidate(mc, m, abs, constraint, _, _) and
1694-
BlanketImplementation::SatisfiesBlanketConstraint<MethodCallCand, SatisfiesBlanketConstraintInput>::satisfiesBlanketConstraint(mcc,
1695-
m)
1679+
BlanketImplementation::satisfiesBlanketConstraint(mcc, m)
16961680
)
16971681
}
16981682

0 commit comments

Comments
 (0)