Skip to content

Commit 9dfb6ea

Browse files
authored
Merge pull request #61675 from slavapestov/element-generic-environment
AST: Opened element generic environments
2 parents 699c0d3 + 74312a3 commit 9dfb6ea

18 files changed

+491
-211
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);
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: 69 additions & 37 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;
@@ -4693,26 +4694,7 @@ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew(
46934694

46944695
Type OpaqueTypeArchetypeType::get(
46954696
OpaqueTypeDecl *Decl, Type interfaceType, SubstitutionMap Substitutions) {
4696-
// TODO: We could attempt to preserve type sugar in the substitution map.
4697-
// Currently archetypes are assumed to be always canonical in many places,
4698-
// though, so doing so would require fixing those places.
4699-
Substitutions = Substitutions.getCanonical();
4700-
4701-
auto &ctx = Decl->getASTContext();
4702-
4703-
// Look for an opaque archetype environment in the appropriate arena.
4704-
auto properties = getOpaqueTypeArchetypeProperties(Substitutions);
4705-
auto arena = getArena(properties);
4706-
auto &environments
4707-
= ctx.getImpl().getArena(arena).OpaqueArchetypeEnvironments;
4708-
GenericEnvironment *env = environments[{Decl, Substitutions}];
4709-
4710-
// Create the environment if it's missing.
4711-
if (!env) {
4712-
env = GenericEnvironment::forOpaqueType(Decl, Substitutions, arena);
4713-
environments[{Decl, Substitutions}] = env;
4714-
}
4715-
4697+
auto *env = GenericEnvironment::forOpaqueType(Decl, Substitutions);
47164698
return env->getOrCreateArchetypeFromInterfaceType(interfaceType);
47174699
}
47184700

@@ -4928,13 +4910,48 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
49284910

49294911
// Allocate and construct the new environment.
49304912
unsigned numGenericParams = signature.getGenericParams().size();
4931-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4932-
OpenedGenericEnvironmentData, Type>(
4913+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4914+
OpenedExistentialEnvironmentData,
4915+
OpenedElementEnvironmentData, Type>(
49334916
0, 0, 0, numGenericParams);
49344917
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
49354918
return new (mem) GenericEnvironment(signature);
49364919
}
49374920

4921+
/// Create a new generic environment for an opaque type with the given set of
4922+
/// outer substitutions.
4923+
GenericEnvironment *GenericEnvironment::forOpaqueType(
4924+
OpaqueTypeDecl *opaque, SubstitutionMap subs) {
4925+
// TODO: We could attempt to preserve type sugar in the substitution map.
4926+
// Currently archetypes are assumed to be always canonical in many places,
4927+
// though, so doing so would require fixing those places.
4928+
subs = subs.getCanonical();
4929+
4930+
auto &ctx = opaque->getASTContext();
4931+
4932+
auto properties = getOpaqueTypeArchetypeProperties(subs);
4933+
auto arena = getArena(properties);
4934+
auto &environments
4935+
= ctx.getImpl().getArena(arena).OpaqueArchetypeEnvironments;
4936+
GenericEnvironment *env = environments[{opaque, subs}];
4937+
4938+
if (!env) {
4939+
// Allocate and construct the new environment.
4940+
auto signature = opaque->getOpaqueInterfaceGenericSignature();
4941+
unsigned numGenericParams = signature.getGenericParams().size();
4942+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4943+
OpenedExistentialEnvironmentData,
4944+
OpenedElementEnvironmentData, Type>(
4945+
1, 0, 0, numGenericParams);
4946+
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
4947+
env = new (mem) GenericEnvironment(signature, opaque, subs);
4948+
4949+
environments[{opaque, subs}] = env;
4950+
}
4951+
4952+
return env;
4953+
}
4954+
49384955
/// Create a new generic environment for an opened archetype.
49394956
GenericEnvironment *
49404957
GenericEnvironment::forOpenedExistential(
@@ -4969,9 +4986,10 @@ GenericEnvironment::forOpenedExistential(
49694986

49704987
// Allocate and construct the new environment.
49714988
unsigned numGenericParams = signature.getGenericParams().size();
4972-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4973-
OpenedGenericEnvironmentData, Type>(
4974-
0, 0, 1, numGenericParams);
4989+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
4990+
OpenedExistentialEnvironmentData,
4991+
OpenedElementEnvironmentData, Type>(
4992+
0, 1, 0, numGenericParams);
49754993
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
49764994
auto *genericEnv =
49774995
new (mem) GenericEnvironment(signature, existential, parentSig, uuid);
@@ -4981,21 +4999,35 @@ GenericEnvironment::forOpenedExistential(
49814999
return genericEnv;
49825000
}
49835001

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();
5002+
/// Create a new generic environment for an element archetype.
5003+
GenericEnvironment *
5004+
GenericEnvironment::forOpenedElement(GenericSignature signature, UUID uuid) {
5005+
auto &ctx = signature->getASTContext();
5006+
5007+
auto &openedElementEnvironments =
5008+
ctx.getImpl().OpenedElementEnvironments;
5009+
auto found = openedElementEnvironments.find(uuid);
5010+
5011+
if (found != openedElementEnvironments.end()) {
5012+
auto *existingEnv = found->second;
5013+
assert(existingEnv->getGenericSignature().getPointer() == signature.getPointer());
5014+
assert(existingEnv->getOpenedElementUUID() == uuid);
5015+
5016+
return existingEnv;
5017+
}
49895018

49905019
// Allocate and construct the new environment.
4991-
auto signature = opaque->getOpaqueInterfaceGenericSignature();
49925020
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;
5021+
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5022+
OpenedExistentialEnvironmentData,
5023+
OpenedElementEnvironmentData, Type>(
5024+
0, 0, 1, numGenericParams);
5025+
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
5026+
auto *genericEnv = new (mem) GenericEnvironment(signature, uuid);
5027+
5028+
openedElementEnvironments[uuid] = genericEnv;
5029+
5030+
return genericEnv;
49995031
}
50005032

50015033
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
@@ -3913,6 +3913,11 @@ namespace {
39133913
OS << "\n";
39143914
PrintWithColorRAII(OS, ParenthesisColor) << ')';
39153915
}
3916+
void visitElementArchetypeType(ElementArchetypeType *T, StringRef label) {
3917+
printArchetypeCommon(T, "element_archetype_type", label);
3918+
printField("opened_element_id", T->getOpenedElementID());
3919+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3920+
}
39163921

39173922
void visitGenericTypeParamType(GenericTypeParamType *T, StringRef label) {
39183923
printCommon(label, "generic_type_param_type");

0 commit comments

Comments
 (0)