Skip to content

Commit 34506bf

Browse files
committed
Rework OpenedArchetypeType to generalize over interface types.
Form opened archetype types based on an interface type and existential type, rather than assuming all OpenedArchetypeType instances only represent the root. Sink the UUID, existential type, and actual creation of the opened archetype into the opened generic environment, so we consistently only create new archetype instances from the generic environment. This slims down OpenedArchetypeType and makes it work similarly to the other archetype kinds, as well as generalizing it to support nested types. Sink the existential type and UUID of an
1 parent b30c5b8 commit 34506bf

File tree

9 files changed

+211
-99
lines changed

9 files changed

+211
-99
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/GenericSignature.h"
2424
#include "swift/Basic/Compiler.h"
2525
#include "swift/Basic/Debug.h"
26+
#include "swift/Basic/UUID.h"
2627
#include "llvm/ADT/ArrayRef.h"
2728
#include "llvm/Support/ErrorHandling.h"
2829
#include "llvm/Support/TrailingObjects.h"
@@ -50,6 +51,12 @@ class QueryInterfaceTypeSubstitutions {
5051
Type operator()(SubstitutableType *type) const;
5152
};
5253

54+
/// Extra data in a generic environment for an opened existentiak.
55+
struct OpenedGenericEnvironmentData {
56+
Type existential;
57+
UUID uuid;
58+
};
59+
5360
/// Describes the mapping between archetypes and interface types for the
5461
/// generic parameters of a DeclContext.
5562
///
@@ -60,7 +67,8 @@ class QueryInterfaceTypeSubstitutions {
6067
///
6168
class alignas(1 << DeclAlignInBits) GenericEnvironment final
6269
: private llvm::TrailingObjects<
63-
GenericEnvironment, OpaqueTypeDecl *, SubstitutionMap, Type> {
70+
GenericEnvironment, OpaqueTypeDecl *, SubstitutionMap,
71+
OpenedGenericEnvironmentData, Type> {
6472
public:
6573
enum class Kind {
6674
/// A normal generic environment, determined only by its generic
@@ -85,6 +93,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
8593
size_t numTrailingObjects(OverloadToken<OpaqueTypeDecl *>) const;
8694
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
8795
size_t numTrailingObjects(OverloadToken<Type>) const;
96+
size_t numTrailingObjects(OverloadToken<OpenedGenericEnvironmentData>) const;
8897

8998
/// Retrieve the array containing the context types associated with the
9099
/// generic parameters, stored in parallel with the generic parameters of the
@@ -99,7 +108,9 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
99108
/// Get the nested type storage, allocating it if required.
100109
NestedTypeStorage &getOrCreateNestedTypeStorage();
101110

102-
explicit GenericEnvironment(GenericSignature signature, Kind kind);
111+
explicit GenericEnvironment(GenericSignature signature);
112+
explicit GenericEnvironment(
113+
GenericSignature signature, Type existential, UUID uuid);
103114
explicit GenericEnvironment(
104115
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs);
105116

@@ -122,6 +133,12 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
122133

123134
TypeArrayView<GenericTypeParamType> getGenericParams() const;
124135

136+
/// Retrieve the existential type for an opened existential environment.
137+
Type getOpenedExistentialType() const;
138+
139+
/// Retrieve the UUID for an opened existential environment.
140+
UUID getOpenedExistentialUUID() const;
141+
125142
/// Retrieve the opaque type declaration for a generic environment describing
126143
/// opaque types.
127144
OpaqueTypeDecl *getOpaqueTypeDecl() const;
@@ -136,8 +153,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
136153
GenericEnvironment *getIncomplete(GenericSignature signature);
137154

138155
/// Create a new generic environment for an opened existential.
139-
static GenericEnvironment *forOpenedExistential(
140-
GenericSignature signature, const OpenedArchetypeType *type);
156+
static GenericEnvironment *forOpenedExistential(Type existential, UUID uuid);
141157

142158
/// Create a new generic environment for an opaque type with the given set of
143159
/// outer substitutions.

include/swift/AST/Types.h

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5566,7 +5566,7 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
55665566
static bool classof(const TypeBase *T) {
55675567
return T->getKind() == TypeKind::OpaqueTypeArchetype;
55685568
}
5569-
5569+
55705570
private:
55715571
OpaqueTypeArchetypeType(GenericEnvironment *environment,
55725572
RecursiveTypeProperties properties,
@@ -5630,21 +5630,49 @@ class OpenedArchetypeType final : public ArchetypeType,
56305630
{
56315631
friend TrailingObjects;
56325632
friend ArchetypeType;
5633-
5633+
friend GenericEnvironment;
5634+
56345635
TypeBase *Opened;
56355636
UUID ID;
56365637

5638+
/// Create a new opened archetype in the given environment representing
5639+
/// the interface type.
5640+
///
5641+
/// This is only invoked by the generic environment when mapping the
5642+
/// interface type into context.
5643+
static CanTypeWrapper<OpenedArchetypeType>
5644+
getNew(GenericEnvironment *environment, Type interfaceType,
5645+
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
5646+
LayoutConstraint layout);
5647+
56375648
public:
5638-
/// Create a new archetype that represents the opened type
5649+
/// Get or create an archetype that represents the opened type
56395650
/// of an existential value.
56405651
///
56415652
/// \param existential The existential type to open.
56425653
///
56435654
/// \param knownID When non-empty, the known ID of the archetype. When empty,
56445655
/// a fresh archetype with a unique ID will be opened.
5645-
static CanTypeWrapper<OpenedArchetypeType>
5646-
get(Type existential,
5647-
Optional<UUID> knownID = None);
5656+
static CanTypeWrapper<OpenedArchetypeType> get(
5657+
Type existential, Optional<UUID> knownID = None);
5658+
5659+
/// Get or create an archetype that represents the opened type
5660+
/// of an existential value.
5661+
///
5662+
/// \param existential The existential type to open.
5663+
/// \param interfaceType The interface type represented by this archetype.
5664+
///
5665+
/// \param knownID When non-empty, the known ID of the archetype. When empty,
5666+
/// a fresh archetype with a unique ID will be opened.
5667+
static CanTypeWrapper<OpenedArchetypeType> get(
5668+
Type existential, Type interfaceType, Optional<UUID> knownID = None);
5669+
5670+
/// Create a new archetype that represents the opened type
5671+
/// of an existential value.
5672+
///
5673+
/// \param existential The existential type or existential metatype to open.
5674+
/// \param interfaceType The interface type represented by this archetype.
5675+
static CanType getAny(Type existential, Type interfaceType);
56485676

56495677
/// Create a new archetype that represents the opened type
56505678
/// of an existential value.
@@ -5653,22 +5681,19 @@ class OpenedArchetypeType final : public ArchetypeType,
56535681
static CanType getAny(Type existential);
56545682

56555683
/// Retrieve the ID number of this opened existential.
5656-
UUID getOpenedExistentialID() const { return ID; }
5684+
UUID getOpenedExistentialID() const;
56575685

56585686
/// Retrieve the opened existential type
5659-
Type getOpenedExistentialType() const {
5660-
return Opened;
5661-
}
5687+
Type getOpenedExistentialType() const;
56625688

56635689
static bool classof(const TypeBase *T) {
56645690
return T->getKind() == TypeKind::OpenedArchetype;
56655691
}
56665692

56675693
private:
5668-
OpenedArchetypeType(const ASTContext &Ctx,
5669-
Type Existential,
5670-
ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
5671-
LayoutConstraint Layout, UUID uuid);
5694+
OpenedArchetypeType(GenericEnvironment *environment, Type interfaceType,
5695+
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
5696+
LayoutConstraint layout);
56725697
};
56735698
BEGIN_CAN_TYPE_WRAPPER(OpenedArchetypeType, ArchetypeType)
56745699
END_CAN_TYPE_WRAPPER(OpenedArchetypeType, ArchetypeType)

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
250250

251251
void remapOpenedType(CanOpenedArchetypeType archetypeTy) {
252252
auto existentialTy = archetypeTy->getOpenedExistentialType()->getCanonicalType();
253-
auto replacementTy = OpenedArchetypeType::get(getOpASTType(existentialTy));
253+
auto replacementTy = OpenedArchetypeType::get(
254+
getOpASTType(existentialTy),
255+
archetypeTy->getInterfaceType());
254256
registerOpenedExistentialRemapping(archetypeTy, replacementTy);
255257
}
256258

lib/AST/ASTContext.cpp

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ struct ASTContext::Implementation {
464464
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
465465
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
466466
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
467-
llvm::DenseMap<UUID, OpenedArchetypeType *> OpenedExistentialArchetypes;
467+
llvm::DenseMap<UUID, GenericEnvironment *> OpenedExistentialEnvironments;
468468
llvm::FoldingSet<IndexSubset> IndexSubsets;
469469
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
470470
AutoDiffDerivativeFunctionIdentifiers;
@@ -2498,7 +2498,7 @@ size_t ASTContext::getTotalMemory() const {
24982498
// getImpl().BuiltinVectorTypes ?
24992499
// getImpl().GenericSignatures ?
25002500
// getImpl().CompoundNames ?
2501-
getImpl().OpenedExistentialArchetypes.getMemorySize() +
2501+
getImpl().OpenedExistentialEnvironments.getMemorySize() +
25022502
getImpl().Permanent.getTotalMemory();
25032503

25042504
Size += getSolverMemory();
@@ -4268,17 +4268,44 @@ Type OpaqueTypeArchetypeType::get(
42684268
return env->getOrCreateArchetypeFromInterfaceType(interfaceType);
42694269
}
42704270

4271+
CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
4272+
GenericEnvironment *environment, Type interfaceType,
4273+
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
4274+
LayoutConstraint layout) {
4275+
auto arena = AllocationArena::Permanent;
4276+
ASTContext &ctx = interfaceType->getASTContext();
4277+
void *mem = ctx.Allocate(
4278+
OpenedArchetypeType::totalSizeToAlloc<ProtocolDecl *,Type,LayoutConstraint>(
4279+
conformsTo.size(),
4280+
superclass ? 1 : 0,
4281+
layout ? 1 : 0),
4282+
alignof(OpenedArchetypeType), arena);
4283+
4284+
return CanOpenedArchetypeType(::new (mem) OpenedArchetypeType(
4285+
environment, interfaceType, conformsTo, superclass, layout));
4286+
}
4287+
4288+
CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::get(
4289+
Type existential, Optional<UUID> knownID) {
4290+
Type interfaceType = GenericTypeParamType::get(
4291+
/*isTypeSequence=*/false, 0, 0, existential->getASTContext());
4292+
return get(existential, interfaceType, knownID);
4293+
}
4294+
42714295
CanOpenedArchetypeType OpenedArchetypeType::get(Type existential,
4296+
Type interfaceType,
42724297
Optional<UUID> knownID) {
42734298
auto &ctx = existential->getASTContext();
4274-
auto &openedExistentialArchetypes = ctx.getImpl().OpenedExistentialArchetypes;
4299+
auto &openedExistentialEnvironments =
4300+
ctx.getImpl().OpenedExistentialEnvironments;
42754301
// If we know the ID already...
42764302
if (knownID) {
42774303
// ... and we already have an archetype for that ID, return it.
4278-
auto found = openedExistentialArchetypes.find(*knownID);
4304+
auto found = openedExistentialEnvironments.find(*knownID);
42794305

4280-
if (found != openedExistentialArchetypes.end()) {
4281-
auto result = found->second;
4306+
if (found != openedExistentialEnvironments.end()) {
4307+
auto result = found->second->mapTypeIntoContext(interfaceType)
4308+
->castTo<OpenedArchetypeType>();
42824309
assert(result->getOpenedExistentialType()->isEqual(existential) &&
42834310
"Retrieved the wrong opened existential type?");
42844311
return CanOpenedArchetypeType(result);
@@ -4288,52 +4315,32 @@ CanOpenedArchetypeType OpenedArchetypeType::get(Type existential,
42884315
knownID = UUID::fromTime();
42894316
}
42904317

4291-
auto layout = existential->getExistentialLayout();
4292-
4293-
SmallVector<ProtocolDecl *, 2> protos;
4294-
for (auto proto : layout.getProtocols())
4295-
protos.push_back(proto->getDecl());
4296-
4297-
auto layoutConstraint = layout.getLayoutConstraint();
4298-
if (!layoutConstraint && layout.requiresClass()) {
4299-
layoutConstraint = LayoutConstraint::getLayoutConstraint(
4300-
LayoutConstraintKind::Class);
4301-
}
4302-
4303-
auto layoutSuperclass = layout.getSuperclass();
4304-
4305-
auto arena = AllocationArena::Permanent;
4306-
void *mem = ctx.Allocate(
4307-
OpenedArchetypeType::totalSizeToAlloc<ProtocolDecl *, Type, LayoutConstraint>(
4308-
protos.size(),
4309-
layoutSuperclass ? 1 : 0,
4310-
layoutConstraint ? 1 : 0),
4311-
alignof(OpenedArchetypeType), arena);
4312-
4313-
auto result =
4314-
::new (mem) OpenedArchetypeType(ctx, existential,
4315-
protos, layoutSuperclass,
4316-
layoutConstraint, *knownID);
4317-
result->InterfaceType =
4318-
GenericTypeParamType::get(/*type sequence*/ false,
4319-
/*depth*/ 0, /*index*/ 0, ctx);
4320-
4321-
auto signature = ctx.getOpenedArchetypeSignature(existential);
4322-
result->Environment = GenericEnvironment::forOpenedExistential(
4323-
signature, result);
4324-
4325-
openedExistentialArchetypes[*knownID] = result;
4318+
/// Create a generic environment for this opened archetype.
4319+
auto genericEnv = GenericEnvironment::forOpenedExistential(
4320+
existential, *knownID);
4321+
openedExistentialEnvironments[*knownID] = genericEnv;
43264322

4323+
// Map the interface type into that environment.
4324+
auto result = genericEnv->mapTypeIntoContext(interfaceType)
4325+
->castTo<OpenedArchetypeType>();
43274326
return CanOpenedArchetypeType(result);
43284327
}
43294328

4330-
CanType OpenedArchetypeType::getAny(Type existential) {
4329+
4330+
CanType OpenedArchetypeType::getAny(Type existential, Type interfaceType) {
43314331
if (auto metatypeTy = existential->getAs<ExistentialMetatypeType>()) {
43324332
auto instanceTy = metatypeTy->getExistentialInstanceType();
4333-
return CanMetatypeType::get(OpenedArchetypeType::getAny(instanceTy));
4333+
return CanMetatypeType::get(
4334+
OpenedArchetypeType::getAny(instanceTy, interfaceType));
43344335
}
43354336
assert(existential->isExistentialType());
4336-
return OpenedArchetypeType::get(existential);
4337+
return OpenedArchetypeType::get(existential, interfaceType);
4338+
}
4339+
4340+
CanType OpenedArchetypeType::getAny(Type existential) {
4341+
Type interfaceType = GenericTypeParamType::get(
4342+
/*isTypeSequence=*/false, 0, 0, existential->getASTContext());
4343+
return getAny(existential, interfaceType);
43374344
}
43384345

43394346
void SubstitutionMap::Storage::Profile(
@@ -4480,27 +4487,26 @@ GenericEnvironment *GenericEnvironment::getIncomplete(
44804487

44814488
// Allocate and construct the new environment.
44824489
unsigned numGenericParams = signature.getGenericParams().size();
4483-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4484-
0, 0, numGenericParams);
4490+
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4491+
OpenedGenericEnvironmentData, Type>(
4492+
0, 0, 0, numGenericParams);
44854493
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
4486-
return new (mem) GenericEnvironment(signature, Kind::Normal);
4494+
return new (mem) GenericEnvironment(signature);
44874495
}
44884496

44894497
/// Create a new generic environment for an opened archetype.
44904498
GenericEnvironment *GenericEnvironment::forOpenedExistential(
4491-
GenericSignature signature, const OpenedArchetypeType *type) {
4492-
auto &ctx = signature->getASTContext();
4499+
Type existential, UUID uuid) {
4500+
auto &ctx = existential->getASTContext();
4501+
auto signature = ctx.getOpenedArchetypeSignature(existential);
44934502

44944503
// Allocate and construct the new environment.
44954504
unsigned numGenericParams = signature.getGenericParams().size();
4496-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4497-
0, 0, numGenericParams);
4505+
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4506+
OpenedGenericEnvironmentData, Type>(
4507+
0, 0, 1, numGenericParams);
44984508
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
4499-
auto env = new (mem) GenericEnvironment(signature, Kind::OpenedExistential);
4500-
env->addMapping(
4501-
signature.getGenericParams().front(),
4502-
Type(const_cast<OpenedArchetypeType *>(type)));
4503-
return env;
4509+
return new (mem) GenericEnvironment(signature, existential, uuid);
45044510
}
45054511

45064512
/// Create a new generic environment for an opaque type with the given set of
@@ -4512,8 +4518,9 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
45124518
// Allocate and construct the new environment.
45134519
auto signature = opaque->getOpaqueInterfaceGenericSignature();
45144520
unsigned numGenericParams = signature.getGenericParams().size();
4515-
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap, Type>(
4516-
1, 1, numGenericParams);
4521+
size_t bytes = totalSizeToAlloc<OpaqueTypeDecl *, SubstitutionMap,
4522+
OpenedGenericEnvironmentData, Type>(
4523+
1, 1, 0, numGenericParams);
45174524
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
45184525
auto env = new (mem) GenericEnvironment(signature, opaque, subs);
45194526
return env;

0 commit comments

Comments
 (0)