Skip to content

Commit 68514b1

Browse files
committed
AST: Introduce ElementArchetypeType
1 parent 82d78a3 commit 68514b1

18 files changed

+451
-182
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,24 @@ class QueryInterfaceTypeSubstitutions {
5151
Type operator()(SubstitutableType *type) const;
5252
};
5353

54+
/// Extra data in a generic environment for an opaque type.
55+
struct OpaqueEnvironmentData {
56+
OpaqueTypeDecl *decl;
57+
SubstitutionMap subMap;
58+
};
59+
5460
/// Extra data in a generic environment for an opened existential.
55-
struct OpenedGenericEnvironmentData {
61+
struct OpenedExistentialEnvironmentData {
5662
Type existential;
5763
GenericSignature parentSig;
5864
UUID uuid;
5965
};
6066

67+
/// Extra data in a generic environment for an opened element.
68+
struct OpenedElementEnvironmentData {
69+
UUID uuid;
70+
};
71+
6172
/// Describes the mapping between archetypes and interface types for the
6273
/// generic parameters of a DeclContext.
6374
///
@@ -68,17 +79,23 @@ struct OpenedGenericEnvironmentData {
6879
///
6980
class alignas(1 << DeclAlignInBits) GenericEnvironment final
7081
: private llvm::TrailingObjects<
71-
GenericEnvironment, OpaqueTypeDecl *, SubstitutionMap,
72-
OpenedGenericEnvironmentData, Type> {
82+
GenericEnvironment,
83+
OpaqueEnvironmentData,
84+
OpenedExistentialEnvironmentData,
85+
OpenedElementEnvironmentData,
86+
Type> {
7387
public:
7488
enum class Kind {
7589
/// A normal generic environment, determined only by its generic
7690
/// signature.
7791
Primary,
78-
/// A generic environment describing an opened existential archetype.
79-
OpenedExistential,
8092
/// A generic environment describing an opaque type archetype.
8193
Opaque,
94+
/// A generic environment describing an opened existential archetype.
95+
OpenedExistential,
96+
/// A generic environment describing an opened element type of a
97+
/// pack archetype inside a pack expansion expression.
98+
OpenedElement,
8299
};
83100

84101
class NestedTypeStorage;
@@ -91,10 +108,10 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
91108
friend TrailingObjects;
92109
friend OpaqueTypeArchetypeType;
93110

94-
size_t numTrailingObjects(OverloadToken<OpaqueTypeDecl *>) const;
95-
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
111+
size_t numTrailingObjects(OverloadToken<OpaqueEnvironmentData>) const;
112+
size_t numTrailingObjects(OverloadToken<OpenedExistentialEnvironmentData>) const;
113+
size_t numTrailingObjects(OverloadToken<OpenedElementEnvironmentData>) const;
96114
size_t numTrailingObjects(OverloadToken<Type>) const;
97-
size_t numTrailingObjects(OverloadToken<OpenedGenericEnvironmentData>) const;
98115

99116
/// Retrieve the array containing the context types associated with the
100117
/// generic parameters, stored in parallel with the generic parameters of the
@@ -109,12 +126,20 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
109126
/// Get the nested type storage, allocating it if required.
110127
NestedTypeStorage &getOrCreateNestedTypeStorage();
111128

129+
/// Private constructor for primary environments.
112130
explicit GenericEnvironment(GenericSignature signature);
131+
132+
/// Private constructor for opaque type environments.
133+
explicit GenericEnvironment(
134+
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs);
135+
136+
/// Private constructor for opened existential environments.
113137
explicit GenericEnvironment(
114138
GenericSignature signature,
115139
Type existential, GenericSignature parentSig, UUID uuid);
116-
explicit GenericEnvironment(
117-
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs);
140+
141+
/// Private constructor for opened element environments.
142+
explicit GenericEnvironment(GenericSignature signature, UUID uuid);
118143

119144
friend ArchetypeType;
120145
friend QueryInterfaceTypeSubstitutions;
@@ -156,9 +181,17 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
156181
/// create a generic environment.
157182
SubstitutionMap getOpaqueSubstitutions() const;
158183

184+
/// Retrieve the UUID for an opened element environment.
185+
UUID getOpenedElementUUID() const;
186+
159187
/// Create a new, primary generic environment.
160188
static GenericEnvironment *forPrimary(GenericSignature signature);
161189

190+
/// Create a new generic environment for an opaque type with the given set of
191+
/// outer substitutions.
192+
static GenericEnvironment *forOpaqueType(
193+
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena);
194+
162195
/// Create a new generic environment for an opened existential.
163196
///
164197
/// \param existential The subject existential type
@@ -167,10 +200,14 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
167200
static GenericEnvironment *
168201
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);
169202

170-
/// Create a new generic environment for an opaque type with the given set of
171-
/// outer substitutions.
172-
static GenericEnvironment *forOpaqueType(
173-
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena);
203+
/// Create a new generic environment for an opened element.
204+
///
205+
/// \param signature The opened element signature, which is the same as the
206+
/// signature of the context whose element type is being opened, but with
207+
/// the pack parameter bit erased from one or more generic parameters
208+
/// \param uuid The unique identifier for this opened element
209+
static GenericEnvironment *
210+
forOpenedElement(GenericSignature signature, UUID uuid);
174211

175212
/// Make vanilla new/delete illegal.
176213
void *operator new(size_t Bytes) = delete;

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ ABSTRACT_TYPE(Substitutable, Type)
148148
ALWAYS_CANONICAL_TYPE(PrimaryArchetype, ArchetypeType)
149149
ALWAYS_CANONICAL_TYPE(OpaqueTypeArchetype, ArchetypeType)
150150
ALWAYS_CANONICAL_TYPE(OpenedArchetype, ArchetypeType)
151+
ALWAYS_CANONICAL_TYPE(ElementArchetype, ArchetypeType)
151152
ALWAYS_CANONICAL_TYPE(PackArchetype, ArchetypeType)
152153
TYPE_RANGE(Archetype, PrimaryArchetype, PackArchetype)
153154
TYPE(GenericTypeParam, SubstitutableType)

include/swift/AST/Types.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ class RecursiveTypeProperties {
125125
HasTypeVariable = 0x01,
126126

127127
/// This type expression contains a context-dependent archetype, either a
128-
/// \c PrimaryArchetypeType, \c OpenedArchetypeType, or
129-
/// \c PackArchetype.
128+
/// \c PrimaryArchetypeType, \c OpenedArchetypeType,
129+
/// \c ElementArchetypeType, or \c PackArchetype.
130130
HasArchetype = 0x02,
131131

132132
/// This type expression contains a GenericTypeParamType.
@@ -6040,6 +6040,52 @@ class PackArchetypeType final
60406040
BEGIN_CAN_TYPE_WRAPPER(PackArchetypeType, ArchetypeType)
60416041
END_CAN_TYPE_WRAPPER(PackArchetypeType, ArchetypeType)
60426042

6043+
/// An archetype that represents the element type of a pack archetype.
6044+
class ElementArchetypeType final : public ArchetypeType,
6045+
private ArchetypeTrailingObjects<ElementArchetypeType>
6046+
{
6047+
friend TrailingObjects;
6048+
friend ArchetypeType;
6049+
friend GenericEnvironment;
6050+
6051+
UUID ID;
6052+
6053+
/// Create a new element archetype in the given environment representing
6054+
/// the interface type.
6055+
///
6056+
/// This is only invoked by the generic environment when mapping the
6057+
/// interface type into context.
6058+
static CanTypeWrapper<ElementArchetypeType>
6059+
getNew(GenericEnvironment *environment, Type interfaceType,
6060+
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
6061+
LayoutConstraint layout);
6062+
6063+
public:
6064+
/// Retrieve the ID number of this opened element.
6065+
UUID getOpenedElementID() const;
6066+
6067+
/// Return the archetype that represents the root generic parameter of its
6068+
/// interface type.
6069+
ElementArchetypeType *getRoot() const {
6070+
return cast<ElementArchetypeType>(ArchetypeType::getRoot());
6071+
}
6072+
6073+
static bool classof(const TypeBase *T) {
6074+
return T->getKind() == TypeKind::ElementArchetype;
6075+
}
6076+
6077+
private:
6078+
ElementArchetypeType(const ASTContext &ctx,
6079+
GenericEnvironment *environment, Type interfaceType,
6080+
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
6081+
LayoutConstraint layout);
6082+
};
6083+
BEGIN_CAN_TYPE_WRAPPER(ElementArchetypeType, ArchetypeType)
6084+
CanElementArchetypeType getRoot() const {
6085+
return CanElementArchetypeType(getPointer()->getRoot());
6086+
}
6087+
END_CAN_TYPE_WRAPPER(ElementArchetypeType, ArchetypeType)
6088+
60436089
template<typename Type>
60446090
const Type *ArchetypeType::getSubclassTrailingObjects() const {
60456091
if (auto contextTy = dyn_cast<PrimaryArchetypeType>(this)) {
@@ -6054,6 +6100,9 @@ const Type *ArchetypeType::getSubclassTrailingObjects() const {
60546100
if (auto childTy = dyn_cast<PackArchetypeType>(this)) {
60556101
return childTy->getTrailingObjects<Type>();
60566102
}
6103+
if (auto childTy = dyn_cast<ElementArchetypeType>(this)) {
6104+
return childTy->getTrailingObjects<Type>();
6105+
}
60576106
llvm_unreachable("unhandled ArchetypeType subclass?");
60586107
}
60596108

lib/AST/ASTContext.cpp

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ struct ASTContext::Implementation {
495495
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
496496
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
497497
llvm::DenseMap<UUID, GenericEnvironment *> OpenedExistentialEnvironments;
498+
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
498499
llvm::FoldingSet<IndexSubset> IndexSubsets;
499500
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
500501
AutoDiffDerivativeFunctionIdentifiers;
@@ -4928,13 +4929,32 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
49284929

49294930
// Allocate and construct the new environment.
49304931
unsigned numGenericParams = signature.getGenericParams().size();
4931-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4932-
OpenedGenericEnvironmentData, Type>(
4932+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4933+
OpenedExistentialEnvironmentData,
4934+
OpenedElementEnvironmentData, Type>(
49334935
0, 0, 0, numGenericParams);
49344936
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
49354937
return new (mem) GenericEnvironment(signature);
49364938
}
49374939

4940+
/// Create a new generic environment for an opaque type with the given set of
4941+
/// outer substitutions.
4942+
GenericEnvironment *GenericEnvironment::forOpaqueType(
4943+
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena) {
4944+
auto &ctx = opaque->getASTContext();
4945+
4946+
// Allocate and construct the new environment.
4947+
auto signature = opaque->getOpaqueInterfaceGenericSignature();
4948+
unsigned numGenericParams = signature.getGenericParams().size();
4949+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4950+
OpenedExistentialEnvironmentData,
4951+
OpenedElementEnvironmentData, Type>(
4952+
1, 0, 0, numGenericParams);
4953+
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
4954+
auto env = new (mem) GenericEnvironment(signature, opaque, subs);
4955+
return env;
4956+
}
4957+
49384958
/// Create a new generic environment for an opened archetype.
49394959
GenericEnvironment *
49404960
GenericEnvironment::forOpenedExistential(
@@ -4969,9 +4989,10 @@ GenericEnvironment::forOpenedExistential(
49694989

49704990
// Allocate and construct the new environment.
49714991
unsigned numGenericParams = signature.getGenericParams().size();
4972-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4973-
OpenedGenericEnvironmentData, Type>(
4974-
0, 0, 1, numGenericParams);
4992+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4993+
OpenedExistentialEnvironmentData,
4994+
OpenedElementEnvironmentData, Type>(
4995+
0, 1, 0, numGenericParams);
49754996
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
49764997
auto *genericEnv =
49774998
new (mem) GenericEnvironment(signature, existential, parentSig, uuid);
@@ -4981,21 +5002,35 @@ GenericEnvironment::forOpenedExistential(
49815002
return genericEnv;
49825003
}
49835004

4984-
/// Create a new generic environment for an opaque type with the given set of
4985-
/// outer substitutions.
4986-
GenericEnvironment *GenericEnvironment::forOpaqueType(
4987-
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena) {
4988-
auto &ctx = opaque->getASTContext();
5005+
/// Create a new generic environment for an element archetype.
5006+
GenericEnvironment *
5007+
GenericEnvironment::forOpenedElement(GenericSignature signature, UUID uuid) {
5008+
auto &ctx = signature->getASTContext();
5009+
5010+
auto &openedElementEnvironments =
5011+
ctx.getImpl().OpenedElementEnvironments;
5012+
auto found = openedElementEnvironments.find(uuid);
5013+
5014+
if (found != openedElementEnvironments.end()) {
5015+
auto *existingEnv = found->second;
5016+
assert(existingEnv->getGenericSignature().getPointer() == signature.getPointer());
5017+
assert(existingEnv->getOpenedElementUUID() == uuid);
5018+
5019+
return existingEnv;
5020+
}
49895021

49905022
// Allocate and construct the new environment.
4991-
auto signature = opaque->getOpaqueInterfaceGenericSignature();
49925023
unsigned numGenericParams = signature.getGenericParams().size();
4993-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4994-
OpenedGenericEnvironmentData, Type>(
4995-
1, 1, 0, numGenericParams);
4996-
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
4997-
auto env = new (mem) GenericEnvironment(signature, opaque, subs);
4998-
return env;
5024+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5025+
OpenedExistentialEnvironmentData,
5026+
OpenedElementEnvironmentData, Type>(
5027+
0, 0, 1, numGenericParams);
5028+
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
5029+
auto *genericEnv = new (mem) GenericEnvironment(signature, uuid);
5030+
5031+
openedElementEnvironments[uuid] = genericEnv;
5032+
5033+
return genericEnv;
49995034
}
50005035

50015036
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3881,6 +3881,11 @@ namespace {
38813881
OS << "\n";
38823882
PrintWithColorRAII(OS, ParenthesisColor) << ')';
38833883
}
3884+
void visitElementArchetypeType(ElementArchetypeType *T, StringRef label) {
3885+
printArchetypeCommon(T, "element_archetype_type", label);
3886+
printField("opened_element_id", T->getOpenedElementID());
3887+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3888+
}
38843889

38853890
void visitGenericTypeParamType(GenericTypeParamType *T, StringRef label) {
38863891
printCommon(label, "generic_type_param_type");

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,7 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
13911391
// type ::= archetype
13921392
case TypeKind::PrimaryArchetype:
13931393
case TypeKind::PackArchetype:
1394+
case TypeKind::ElementArchetype:
13941395
llvm_unreachable("Cannot mangle free-standing archetypes");
13951396

13961397
case TypeKind::OpenedArchetype: {

lib/AST/ASTPrinter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6370,6 +6370,19 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
63706370
}
63716371
}
63726372

6373+
void visitElementArchetypeType(ElementArchetypeType *T) {
6374+
if (Options.PrintForSIL) {
6375+
Printer << "@element(\"" << T->getOpenedElementID() << ") ";
6376+
visit(T->getGenericEnvironment()->getOpenedExistentialType());
6377+
Printer << ") ";
6378+
6379+
auto interfaceTy = T->getInterfaceType();
6380+
visit(interfaceTy);
6381+
} else {
6382+
visit(T->getInterfaceType());
6383+
}
6384+
}
6385+
63736386
void printDependentMember(DependentMemberType *T) {
63746387
if (auto *const Assoc = T->getAssocType()) {
63756388
if (Options.ProtocolQualifiedDependentMemberTypes) {

0 commit comments

Comments
 (0)