24
24
#include " swift/AST/ExtInfo.h"
25
25
#include " swift/AST/GenericParamKey.h"
26
26
#include " swift/AST/Identifier.h"
27
+ #include " swift/AST/KnownProtocols.h"
27
28
#include " swift/AST/Ownership.h"
28
29
#include " swift/AST/ProtocolConformanceRef.h"
29
30
#include " swift/AST/Requirement.h"
@@ -100,7 +101,6 @@ class ProtocolConformance;
100
101
enum PointerTypeKind : unsigned ;
101
102
struct ValueOwnershipKind ;
102
103
class ErrorExpr ;
103
- enum class KnownProtocolKind : uint8_t ;
104
104
105
105
typedef CanTypeWrapper<SILFunctionType> CanSILFunctionType;
106
106
@@ -1534,6 +1534,48 @@ class NominalOrBoundGenericNominalType : public AnyGenericType {
1534
1534
};
1535
1535
DEFINE_EMPTY_CAN_TYPE_WRAPPER (NominalOrBoundGenericNominalType, AnyGenericType)
1536
1536
1537
+ // / InverseType represents the "inverse" of a ProtocolType as a constraint.
1538
+ // / An inverse represents the _absence_ of an implicit constraint to the given
1539
+ // / protocol.
1540
+ // /
1541
+ // / Otherwise, an inverse is not a real type! It's an annotation for other types
1542
+ // / to signal whether an implicit requirement on that type should be omitted.
1543
+ // / Because that annotation is expressed in the surface language as if it _were_
1544
+ // / a type (that is, as a type constraint) we still model it as a Type through
1545
+ // / typechecking.
1546
+ class InverseType final : public TypeBase {
1547
+ Type protocol;
1548
+
1549
+ InverseType (Type type,
1550
+ const ASTContext *canonicalContext,
1551
+ RecursiveTypeProperties properties)
1552
+ : TypeBase(TypeKind::Inverse, canonicalContext, properties),
1553
+ protocol (type) {
1554
+ assert (protocol->is <ProtocolType>());
1555
+ }
1556
+
1557
+ public:
1558
+ // / Produce an inverse constraint type for the given protocol type.
1559
+ static Type get (Type protocolType);
1560
+
1561
+
1562
+ // / Obtain the underlying \c ProtocolType that was inverted.
1563
+ Type getInvertedProtocol () const {
1564
+ return protocol;
1565
+ }
1566
+
1567
+ // / Get known kind of inverse this type represents.
1568
+ InvertibleProtocolKind getInverseKind () const ;
1569
+
1570
+ // Implement isa/cast/dyncast/etc.
1571
+ static bool classof (const TypeBase *T) {
1572
+ return T->getKind () == TypeKind::Inverse;
1573
+ }
1574
+ };
1575
+ BEGIN_CAN_TYPE_WRAPPER (InverseType, Type)
1576
+ PROXY_CAN_TYPE_SIMPLE_GETTER(getInvertedProtocol)
1577
+ END_CAN_TYPE_WRAPPER(InverseType, Type)
1578
+
1537
1579
// / ErrorType - Represents the type of an erroneously constructed declaration,
1538
1580
// / expression, or type. When creating ErrorTypes, an associated error
1539
1581
// / diagnostic should always be emitted. That way when later stages of
@@ -5739,13 +5781,37 @@ class ProtocolCompositionType final : public TypeBase,
5739
5781
public llvm::FoldingSetNode,
5740
5782
private llvm::TrailingObjects<ProtocolCompositionType, Type> {
5741
5783
friend TrailingObjects;
5784
+
5785
+ // TODO(kavon): this could probably be folded into the existing Bits field
5786
+ // or we could just store the InverseType's in the Members array.
5787
+ InvertibleProtocolSet Inverses;
5742
5788
5743
5789
public:
5744
5790
// / Retrieve an instance of a protocol composition type with the
5745
- // / given set of members.
5791
+ // / given set of members. A "hidden member" is an implicit constraint that
5792
+ // / is present for all protocol compositions.
5793
+ // /
5794
+ // / \param Members the regular members of this composition.
5795
+ // / \param Inverses the set of inverses that are a member of the composition,
5796
+ // / i.e., if \c IP is in this set, then \c ~IP is a member of
5797
+ // / this composition.
5798
+ // / \param HasExplicitAnyObject indicates whether this composition should be
5799
+ // / treated as if \c AnyObject was a member.
5746
5800
static Type get (const ASTContext &C, ArrayRef<Type> Members,
5801
+ InvertibleProtocolSet Inverses,
5747
5802
bool HasExplicitAnyObject);
5748
5803
5804
+ // / Retrieve an instance of a protocol composition type with the
5805
+ // / given set of members. Assumes no inverses are present in \c Members.
5806
+ static Type get (const ASTContext &C, ArrayRef<Type> Members,
5807
+ bool HasExplicitAnyObject);
5808
+
5809
+ // / Constructs a protocol composition corresponding to the `Any` type.
5810
+ static Type theAnyType (const ASTContext &C);
5811
+
5812
+ // / Constructs a protocol composition corresponding to the `AnyObject` type.
5813
+ static Type theAnyObjectType (const ASTContext &C);
5814
+
5749
5815
// / Canonical protocol composition types are minimized only to a certain
5750
5816
// / degree to preserve ABI compatibility. This routine enables performing
5751
5817
// / slower, but stricter minimization at need (e.g. redeclaration checking).
@@ -5768,11 +5834,14 @@ class ProtocolCompositionType final : public TypeBase,
5768
5834
return {getTrailingObjects<Type>(), Bits.ProtocolCompositionType .Count };
5769
5835
}
5770
5836
5837
+ InvertibleProtocolSet getInverses () const { return Inverses; }
5838
+
5771
5839
void Profile (llvm::FoldingSetNodeID &ID) {
5772
- Profile (ID, getMembers (), hasExplicitAnyObject ());
5840
+ Profile (ID, getMembers (), getInverses (), hasExplicitAnyObject ());
5773
5841
}
5774
5842
static void Profile (llvm::FoldingSetNodeID &ID,
5775
5843
ArrayRef<Type> Members,
5844
+ InvertibleProtocolSet Inverses,
5776
5845
bool HasExplicitAnyObject);
5777
5846
5778
5847
// / True if the composition requires the concrete conforming type to
@@ -5793,12 +5862,15 @@ class ProtocolCompositionType final : public TypeBase,
5793
5862
private:
5794
5863
static ProtocolCompositionType *build (const ASTContext &C,
5795
5864
ArrayRef<Type> Members,
5865
+ InvertibleProtocolSet Inverses,
5796
5866
bool HasExplicitAnyObject);
5797
5867
5798
5868
ProtocolCompositionType (const ASTContext *ctx, ArrayRef<Type> members,
5869
+ InvertibleProtocolSet inverses,
5799
5870
bool hasExplicitAnyObject,
5800
5871
RecursiveTypeProperties properties)
5801
- : TypeBase (TypeKind::ProtocolComposition, /* Context=*/ ctx, properties) {
5872
+ : TypeBase (TypeKind::ProtocolComposition, /* Context=*/ ctx, properties),
5873
+ Inverses (inverses) {
5802
5874
Bits.ProtocolCompositionType .HasExplicitAnyObject = hasExplicitAnyObject;
5803
5875
Bits.ProtocolCompositionType .Count = members.size ();
5804
5876
std::uninitialized_copy (members.begin (), members.end (),
@@ -7223,7 +7295,8 @@ inline bool TypeBase::isConstraintType() const {
7223
7295
inline bool CanType::isConstraintTypeImpl (CanType type) {
7224
7296
return (isa<ProtocolType>(type) ||
7225
7297
isa<ProtocolCompositionType>(type) ||
7226
- isa<ParameterizedProtocolType>(type));
7298
+ isa<ParameterizedProtocolType>(type) ||
7299
+ isa<InverseType>(type));
7227
7300
}
7228
7301
7229
7302
inline bool TypeBase::isExistentialType () {
@@ -7239,6 +7312,7 @@ inline bool CanType::isExistentialTypeImpl(CanType type) {
7239
7312
isa<ProtocolCompositionType>(type) ||
7240
7313
isa<ExistentialType>(type) ||
7241
7314
isa<ParameterizedProtocolType>(type);
7315
+ // TODO(kavon): treat InverseType as an existential, etc?
7242
7316
}
7243
7317
7244
7318
inline bool CanType::isAnyExistentialTypeImpl (CanType type) {
0 commit comments