@@ -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-
996894private 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