Skip to content

Commit 8be4df4

Browse files
authored
Merge pull request #6011 from DougGregor/lazy-nested-types
2 parents 6817217 + 301ef9a commit 8be4df4

File tree

9 files changed

+208
-91
lines changed

9 files changed

+208
-91
lines changed

include/swift/AST/Types.h

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,16 @@ class alignas(1 << TypeAlignInBits) TypeBase {
284284
enum { NumAnyFunctionTypeBits = NumTypeBaseBits + 16 };
285285
static_assert(NumAnyFunctionTypeBits <= 32, "fits in an unsigned");
286286

287+
struct ArchetypeTypeBitfields {
288+
unsigned : NumTypeBaseBits;
289+
290+
unsigned ExpandedNestedTypes : 1;
291+
unsigned HasSuperclass : 1;
292+
unsigned NumProtocols : 16;
293+
};
294+
enum { NumArchetypeTypeBitfields = NumTypeBaseBits + 18 };
295+
static_assert(NumArchetypeTypeBitfields <= 32, "fits in an unsigned");
296+
287297
struct TypeVariableTypeBitfields {
288298
unsigned : NumTypeBaseBits;
289299

@@ -319,6 +329,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
319329
ErrorTypeBitfields ErrorTypeBits;
320330
AnyFunctionTypeBitfields AnyFunctionTypeBits;
321331
TypeVariableTypeBitfields TypeVariableTypeBits;
332+
ArchetypeTypeBitfields ArchetypeTypeBits;
322333
SILFunctionTypeBitfields SILFunctionTypeBits;
323334
AnyMetatypeTypeBitfields AnyMetatypeTypeBits;
324335
};
@@ -3544,6 +3555,16 @@ class ProtocolType : public NominalType, public llvm::FoldingSetNode {
35443555
/// in the protocol list, then sorting them in some stable order.
35453556
static void canonicalizeProtocols(SmallVectorImpl<ProtocolDecl *> &protocols);
35463557

3558+
/// Visit all of the protocols in the given list of protocols, along with their
3559+
///
3560+
/// \param fn Visitor function called for each protocol (just once). If it
3561+
/// returns \c true, the visit operation will abort and return \c true.
3562+
///
3563+
/// \returns \c true if any invocation of \c fn returns \c true, and \c false
3564+
/// otherwise.
3565+
static bool visitAllProtocols(ArrayRef<ProtocolDecl *> protocols,
3566+
llvm::function_ref<bool(ProtocolDecl *)> fn);
3567+
35473568
/// Compare two protocols to provide them with a stable ordering for
35483569
/// use in sorting.
35493570
static int compareProtocols(ProtocolDecl * const* PP1,
@@ -3728,9 +3749,21 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(SubstitutableType, Type)
37283749
/// associated types, as well as the runtime type stored within an
37293750
/// existential container.
37303751
class ArchetypeType final : public SubstitutableType,
3731-
private llvm::TrailingObjects<ArchetypeType, UUID> {
3752+
private llvm::TrailingObjects<ArchetypeType, ProtocolDecl *, Type, UUID> {
37323753
friend TrailingObjects;
37333754

3755+
size_t numTrailingObjects(OverloadToken<ProtocolDecl *>) const {
3756+
return ArchetypeTypeBits.NumProtocols;
3757+
}
3758+
3759+
size_t numTrailingObjects(OverloadToken<Type>) const {
3760+
return ArchetypeTypeBits.HasSuperclass ? 1 : 0;
3761+
}
3762+
3763+
size_t numTrailingObjects(OverloadToken<UUID>) const {
3764+
return getOpenedExistentialType() ? 1 : 0;
3765+
}
3766+
37343767
public:
37353768
/// A nested type. Either a dependent associated archetype, or a concrete
37363769
/// type (which may be a bound archetype from an outer context).
@@ -3774,21 +3807,12 @@ class ArchetypeType final : public SubstitutableType,
37743807
};
37753808

37763809
private:
3777-
ArrayRef<ProtocolDecl *> ConformsTo;
3778-
Type Superclass;
3779-
37803810
llvm::PointerUnion3<ArchetypeType *, TypeBase *,
37813811
GenericEnvironment *> ParentOrOpenedOrEnvironment;
37823812
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName;
37833813
MutableArrayRef<std::pair<Identifier, NestedType>> NestedTypes;
37843814

3785-
/// Set the ID number of this opened existential.
3786-
void setOpenedExistentialID(UUID value) {
3787-
assert(getOpenedExistentialType() && "Not an opened existential archetype");
3788-
// The UUID is tail-allocated at the end of opened existential archetypes.
3789-
*getTrailingObjects<UUID>() = value;
3790-
}
3791-
3815+
void populateNestedTypes() const;
37923816
void resolveNestedType(std::pair<Identifier, NestedType> &nested) const;
37933817

37943818
public:
@@ -3864,15 +3888,22 @@ class ArchetypeType final : public SubstitutableType,
38643888

38653889
/// getConformsTo - Retrieve the set of protocols to which this substitutable
38663890
/// type shall conform.
3867-
ArrayRef<ProtocolDecl *> getConformsTo() const { return ConformsTo; }
3891+
ArrayRef<ProtocolDecl *> getConformsTo() const {
3892+
return { getTrailingObjects<ProtocolDecl *>(),
3893+
ArchetypeTypeBits.NumProtocols };
3894+
}
38683895

38693896
/// requiresClass - True if the type can only be substituted with class types.
38703897
/// This is true if the type conforms to one or more class protocols or has
38713898
/// a superclass constraint.
38723899
bool requiresClass() const;
38733900

38743901
/// \brief Retrieve the superclass of this type, if such a requirement exists.
3875-
Type getSuperclass() const { return Superclass; }
3902+
Type getSuperclass() const {
3903+
if (!ArchetypeTypeBits.HasSuperclass) return Type();
3904+
3905+
return *getTrailingObjects<Type>();
3906+
}
38763907

38773908
/// \brief Return true if the archetype has any requirements at all.
38783909
bool hasRequirements() const {
@@ -3917,9 +3948,9 @@ class ArchetypeType final : public SubstitutableType,
39173948
getAllNestedTypes(bool resolveTypes = true) const;
39183949

39193950
/// \brief Set the nested types to a copy of the given array of
3920-
/// archetypes, which will first be sorted in place.
3951+
/// archetypes.
39213952
void setNestedTypes(ASTContext &Ctx,
3922-
MutableArrayRef<std::pair<Identifier, NestedType>> Nested);
3953+
ArrayRef<std::pair<Identifier, NestedType>> Nested);
39233954

39243955
/// Register a nested type with the given name.
39253956
void registerNestedType(Identifier name, NestedType nested);
@@ -3960,29 +3991,11 @@ class ArchetypeType final : public SubstitutableType,
39603991
ParentOrGenericEnv,
39613992
llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName,
39623993
ArrayRef<ProtocolDecl *> ConformsTo,
3963-
Type Superclass)
3964-
: SubstitutableType(TypeKind::Archetype, &Ctx,
3965-
RecursiveTypeProperties::HasArchetype),
3966-
ConformsTo(ConformsTo), Superclass(Superclass),
3967-
AssocTypeOrName(AssocTypeOrName) {
3968-
if (auto parent = ParentOrGenericEnv.dyn_cast<ArchetypeType *>()) {
3969-
ParentOrOpenedOrEnvironment = parent;
3970-
} else {
3971-
ParentOrOpenedOrEnvironment =
3972-
ParentOrGenericEnv.get<GenericEnvironment *>();
3973-
}
3974-
}
3994+
Type Superclass);
39753995

3976-
ArchetypeType(const ASTContext &Ctx,
3977-
Type Existential,
3978-
ArrayRef<ProtocolDecl *> ConformsTo,
3979-
Type Superclass)
3980-
: SubstitutableType(TypeKind::Archetype, &Ctx,
3981-
RecursiveTypeProperties(
3982-
RecursiveTypeProperties::HasArchetype |
3983-
RecursiveTypeProperties::HasOpenedExistential)),
3984-
ConformsTo(ConformsTo), Superclass(Superclass),
3985-
ParentOrOpenedOrEnvironment(Existential.getPointer()) { }
3996+
ArchetypeType(const ASTContext &Ctx, Type Existential,
3997+
ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
3998+
UUID uuid);
39863999
};
39874000
BEGIN_CAN_TYPE_WRAPPER(ArchetypeType, SubstitutableType)
39884001
CanArchetypeType getParent() const {

lib/AST/ASTContext.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,7 +3418,7 @@ DependentMemberType *DependentMemberType::get(Type base,
34183418
}
34193419

34203420
CanArchetypeType ArchetypeType::getOpened(Type existential,
3421-
Optional<UUID> knownID) {
3421+
Optional<UUID> knownID) {
34223422
auto &ctx = existential->getASTContext();
34233423
auto &openedExistentialArchetypes = ctx.Impl.OpenedExistentialArchetypes;
34243424
// If we know the ID already...
@@ -3437,19 +3437,20 @@ CanArchetypeType ArchetypeType::getOpened(Type existential,
34373437
knownID = UUID::fromTime();
34383438
}
34393439

3440-
auto arena = AllocationArena::Permanent;
34413440
llvm::SmallVector<ProtocolDecl *, 4> conformsTo;
34423441
assert(existential->isExistentialType());
34433442
existential->getAnyExistentialTypeProtocols(conformsTo);
3443+
Type superclass = existential->getSuperclass(nullptr);
34443444

3445-
// Tail-allocate space for the UUID.
3446-
void *archetypeBuf = ctx.Allocate(totalSizeToAlloc<UUID>(1),
3447-
alignof(ArchetypeType), arena);
3448-
3449-
auto result = ::new (archetypeBuf) ArchetypeType(ctx, existential,
3450-
ctx.AllocateCopy(conformsTo),
3451-
existential->getSuperclass(nullptr));
3452-
result->setOpenedExistentialID(*knownID);
3445+
auto arena = AllocationArena::Permanent;
3446+
void *mem = ctx.Allocate(
3447+
totalSizeToAlloc<ProtocolDecl *, Type, UUID>(conformsTo.size(),
3448+
superclass ? 1 : 0,
3449+
1),
3450+
alignof(ArchetypeType), arena);
3451+
3452+
auto result = ::new (mem) ArchetypeType(ctx, existential, conformsTo,
3453+
superclass, *knownID);
34533454
openedExistentialArchetypes[*knownID] = result;
34543455

34553456
return CanArchetypeType(result);

lib/AST/ArchetypeBuilder.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -752,30 +752,6 @@ ArchetypeBuilder::PotentialArchetype::getTypeInContext(
752752
genericEnv->addMapping(getGenericParamKey(), arch);
753753
}
754754

755-
// Collect the set of nested types of this archetype, and put them into
756-
// the archetype itself.
757-
if (!representative->getNestedTypes().empty()) {
758-
SmallVector<std::pair<Identifier, NestedType>, 4> FlatNestedTypes;
759-
for (auto Nested : representative->getNestedTypes()) {
760-
// Skip type aliases, which are just shortcuts.
761-
if (Nested.second.front()->getTypeAliasDecl())
762-
continue;
763-
bool anyNotRenamed = false;
764-
for (auto NestedPA : Nested.second) {
765-
if (!NestedPA->wasRenamed()) {
766-
anyNotRenamed = true;
767-
break;
768-
}
769-
}
770-
771-
if (!anyNotRenamed)
772-
continue;
773-
774-
FlatNestedTypes.push_back({ Nested.first, NestedType() });
775-
}
776-
arch->setNestedTypes(ctx, FlatNestedTypes);
777-
}
778-
779755
return NestedType::forArchetype(arch);
780756
}
781757

0 commit comments

Comments
 (0)