Skip to content

Commit fa55b25

Browse files
authored
Merge pull request #85593 from slavapestov/lazy-opaque-type-decl
Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions
2 parents 8091359 + 2709743 commit fa55b25

File tree

13 files changed

+362
-183
lines changed

13 files changed

+362
-183
lines changed

include/swift/AST/Decl.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,11 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
761761
HasAnyUnavailableDuringLoweringValues : 1
762762
);
763763

764+
SWIFT_INLINE_BITFIELD(OpaqueTypeDecl, GenericTypeDecl, 1,
765+
/// Whether we have lazily-loaded underlying substitutions.
766+
HasLazyUnderlyingSubstitutions : 1
767+
);
768+
764769
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
765770
/// If the module is compiled as static library.
766771
StaticLibrary : 1,
@@ -3646,7 +3651,8 @@ class OpaqueTypeDecl final :
36463651
OpaqueTypeDecl(ValueDecl *NamingDecl, GenericParamList *GenericParams,
36473652
DeclContext *DC,
36483653
GenericSignature OpaqueInterfaceGenericSignature,
3649-
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
3654+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs,
3655+
bool hasLazyUnderlyingSubstitutions);
36503656

36513657
unsigned getNumOpaqueReturnTypeReprs() const {
36523658
return NamingDeclAndHasOpaqueReturnTypeRepr.getInt()
@@ -3658,13 +3664,21 @@ class OpaqueTypeDecl final :
36583664
return getNumOpaqueReturnTypeReprs();
36593665
}
36603666

3667+
void loadLazyUnderlyingSubstitutions();
3668+
36613669
public:
3662-
static OpaqueTypeDecl *get(
3670+
static OpaqueTypeDecl *create(
36633671
ValueDecl *NamingDecl, GenericParamList *GenericParams,
36643672
DeclContext *DC,
36653673
GenericSignature OpaqueInterfaceGenericSignature,
36663674
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
36673675

3676+
static OpaqueTypeDecl *createDeserialized(
3677+
GenericParamList *GenericParams,
3678+
DeclContext *DC,
3679+
GenericSignature OpaqueInterfaceGenericSignature,
3680+
LazyMemberLoader *lazyLoader, uint64_t underlyingSubsData);
3681+
36683682
ValueDecl *getNamingDecl() const {
36693683
return NamingDeclAndHasOpaqueReturnTypeRepr.getPointer();
36703684
}
@@ -3720,19 +3734,19 @@ class OpaqueTypeDecl final :
37203734
bool typeCheckFunctionBodies=true) const;
37213735

37223736
void setUniqueUnderlyingTypeSubstitutions(SubstitutionMap subs) {
3723-
assert(!UniqueUnderlyingType.has_value() && "resetting underlying type?!");
3737+
ASSERT(!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions);
3738+
ASSERT(!UniqueUnderlyingType.has_value() && "resetting underlying type?!");
37243739
UniqueUnderlyingType = subs;
37253740
}
37263741

37273742
bool hasConditionallyAvailableSubstitutions() const {
3743+
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
3744+
37283745
return ConditionallyAvailableTypes.has_value();
37293746
}
37303747

37313748
ArrayRef<ConditionallyAvailableSubstitutions *>
3732-
getConditionallyAvailableSubstitutions() const {
3733-
assert(ConditionallyAvailableTypes);
3734-
return ConditionallyAvailableTypes.value();
3735-
}
3749+
getConditionallyAvailableSubstitutions() const;
37363750

37373751
void setConditionallyAvailableSubstitutions(
37383752
ArrayRef<ConditionallyAvailableSubstitutions *> substitutions);

include/swift/AST/LazyResolver.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class LazyAssociatedTypeData : public LazyContextData {
6363
uint64_t defaultDefinitionTypeData = 0;
6464
};
6565

66+
class LazyOpaqueTypeData : public LazyContextData {
67+
public:
68+
/// The context data used for loading the underlying type substitution map.
69+
uint64_t underlyingSubsData = 0;
70+
};
71+
6672
/// Context data for protocols.
6773
class LazyProtocolData : public LazyIterableDeclContextData {
6874
public:
@@ -138,6 +144,10 @@ class alignas(void*) LazyMemberLoader {
138144
// Returns the target parameter of the `@_specialize` attribute or null.
139145
virtual ValueDecl *loadTargetFunctionDecl(const AbstractSpecializeAttr *attr,
140146
uint64_t contextData) = 0;
147+
148+
/// Loads the underlying type substitution map of an opaque result declaration.
149+
virtual void
150+
finishOpaqueTypeDecl(OpaqueTypeDecl *opaqueDecl, uint64_t contextData) = 0;
141151
};
142152

143153
/// A class that can lazily load conformances from a serialized format.

lib/AST/ASTContext.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,20 +3174,22 @@ ASTContext::getOrCreateLazyContextData(const Decl *decl,
31743174
LazyMemberLoader *lazyLoader) {
31753175
if (auto *data = getLazyContextData(decl)) {
31763176
// Make sure we didn't provide an incompatible lazy loader.
3177-
assert(!lazyLoader || lazyLoader == data->loader);
3177+
ASSERT(!lazyLoader || lazyLoader == data->loader);
31783178
return data;
31793179
}
31803180

31813181
LazyContextData *&entry = getImpl().LazyContexts[decl];
31823182

31833183
// Create new lazy context data with the given loader.
3184-
assert(lazyLoader && "Queried lazy data for non-lazy iterable context");
3184+
ASSERT(lazyLoader && "Queried lazy data for non-lazy iterable context");
31853185
if (isa<ProtocolDecl>(decl)) {
31863186
entry = Allocate<LazyProtocolData>();
31873187
} else if (isa<NominalTypeDecl>(decl) || isa<ExtensionDecl>(decl)) {
31883188
entry = Allocate<LazyIterableDeclContextData>();
3189+
} else if (isa<OpaqueTypeDecl>(decl)) {
3190+
entry = Allocate<LazyOpaqueTypeData>();
31893191
} else {
3190-
assert(isa<AssociatedTypeDecl>(decl));
3192+
ASSERT(isa<AssociatedTypeDecl>(decl));
31913193
entry = Allocate<LazyAssociatedTypeData>();
31923194
}
31933195

lib/AST/Decl.cpp

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10820,13 +10820,16 @@ bool AbstractFunctionDecl::isResilient(ModuleDecl *M,
1082010820
OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
1082110821
GenericParamList *GenericParams, DeclContext *DC,
1082210822
GenericSignature OpaqueInterfaceGenericSignature,
10823-
ArrayRef<TypeRepr *>
10824-
OpaqueReturnTypeReprs)
10823+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs,
10824+
bool hasLazyUnderlyingSubstitutions)
1082510825
: GenericTypeDecl(DeclKind::OpaqueType, DC, Identifier(), SourceLoc(), {},
1082610826
GenericParams),
1082710827
NamingDeclAndHasOpaqueReturnTypeRepr(
1082810828
NamingDecl, !OpaqueReturnTypeReprs.empty()),
1082910829
OpaqueInterfaceGenericSignature(OpaqueInterfaceGenericSignature) {
10830+
Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions
10831+
= hasLazyUnderlyingSubstitutions;
10832+
1083010833
// Always implicit.
1083110834
setImplicit();
1083210835

@@ -10839,7 +10842,7 @@ OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
1083910842
OpaqueReturnTypeReprs.end(), getTrailingObjects());
1084010843
}
1084110844

10842-
OpaqueTypeDecl *OpaqueTypeDecl::get(
10845+
OpaqueTypeDecl *OpaqueTypeDecl::create(
1084310846
ValueDecl *NamingDecl, GenericParamList *GenericParams,
1084410847
DeclContext *DC,
1084510848
GenericSignature OpaqueInterfaceGenericSignature,
@@ -10850,7 +10853,33 @@ OpaqueTypeDecl *OpaqueTypeDecl::get(
1085010853
auto mem = ctx.Allocate(size, alignof(OpaqueTypeDecl));
1085110854
return new (mem) OpaqueTypeDecl(
1085210855
NamingDecl, GenericParams, DC, OpaqueInterfaceGenericSignature,
10853-
OpaqueReturnTypeReprs);
10856+
OpaqueReturnTypeReprs, /*hasLazyUnderlyingSubstitutions=*/false);
10857+
}
10858+
10859+
OpaqueTypeDecl *OpaqueTypeDecl::createDeserialized(
10860+
GenericParamList *GenericParams, DeclContext *DC,
10861+
GenericSignature OpaqueInterfaceGenericSignature,
10862+
LazyMemberLoader *lazyLoader, uint64_t underlyingSubsData) {
10863+
bool hasLazyUnderlyingSubstitutions = (underlyingSubsData != 0);
10864+
10865+
ASTContext &ctx = DC->getASTContext();
10866+
auto size = totalSizeToAlloc<TypeRepr *>(0);
10867+
auto mem = ctx.Allocate(size, alignof(OpaqueTypeDecl));
10868+
10869+
// NamingDecl is set later by deserialization
10870+
auto *decl = new (mem) OpaqueTypeDecl(
10871+
/*namingDecl=*/nullptr, GenericParams, DC,
10872+
OpaqueInterfaceGenericSignature, { },
10873+
hasLazyUnderlyingSubstitutions);
10874+
10875+
if (hasLazyUnderlyingSubstitutions) {
10876+
auto &ctx = DC->getASTContext();
10877+
auto *data = static_cast<LazyOpaqueTypeData *>(
10878+
ctx.getOrCreateLazyContextData(decl, lazyLoader));
10879+
data->underlyingSubsData = underlyingSubsData;
10880+
}
10881+
10882+
return decl;
1085410883
}
1085510884

1085610885
bool OpaqueTypeDecl::isOpaqueReturnTypeOf(const Decl *ownerDecl) const {
@@ -10906,16 +10935,41 @@ bool OpaqueTypeDecl::exportUnderlyingType() const {
1090610935
llvm_unreachable("The naming decl is expected to be either an AFD or ASD");
1090710936
}
1090810937

10938+
void OpaqueTypeDecl::loadLazyUnderlyingSubstitutions() {
10939+
if (!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions)
10940+
return;
10941+
10942+
Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions = 0;
10943+
10944+
auto &ctx = getASTContext();
10945+
auto *data = static_cast<LazyOpaqueTypeData *>(
10946+
ctx.getLazyContextData(this));
10947+
ASSERT(data != nullptr);
10948+
10949+
data->loader->finishOpaqueTypeDecl(
10950+
this, data->underlyingSubsData);
10951+
}
10952+
1090910953
std::optional<SubstitutionMap>
1091010954
OpaqueTypeDecl::getUniqueUnderlyingTypeSubstitutions(
1091110955
bool typeCheckFunctionBodies) const {
10956+
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
10957+
1091210958
if (!typeCheckFunctionBodies)
1091310959
return UniqueUnderlyingType;
1091410960

1091510961
return evaluateOrDefault(getASTContext().evaluator,
1091610962
UniqueUnderlyingTypeSubstitutionsRequest{this}, {});
1091710963
}
1091810964

10965+
ArrayRef<OpaqueTypeDecl::ConditionallyAvailableSubstitutions *>
10966+
OpaqueTypeDecl::getConditionallyAvailableSubstitutions() const {
10967+
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
10968+
10969+
assert(ConditionallyAvailableTypes);
10970+
return ConditionallyAvailableTypes.value();
10971+
}
10972+
1091910973
std::optional<unsigned>
1092010974
OpaqueTypeDecl::getAnonymousOpaqueParamOrdinal(TypeRepr *repr) const {
1092110975
assert(NamingDeclAndHasOpaqueReturnTypeRepr.getInt() &&
@@ -10945,7 +10999,8 @@ Identifier OpaqueTypeDecl::getOpaqueReturnTypeIdentifier() const {
1094510999

1094611000
void OpaqueTypeDecl::setConditionallyAvailableSubstitutions(
1094711001
ArrayRef<ConditionallyAvailableSubstitutions *> substitutions) {
10948-
assert(!ConditionallyAvailableTypes &&
11002+
ASSERT(!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions);
11003+
ASSERT(!ConditionallyAvailableTypes &&
1094911004
"resetting conditionally available substitutions?!");
1095011005
ConditionallyAvailableTypes = getASTContext().AllocateCopy(substitutions);
1095111006
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
17621762
llvm_unreachable("unimplemented for ClangImporter");
17631763
}
17641764

1765+
void finishOpaqueTypeDecl(OpaqueTypeDecl *decl,
1766+
uint64_t contextData) override {
1767+
llvm_unreachable("unimplemented for ClangImporter");
1768+
}
1769+
17651770
template <typename DeclTy, typename ...Targs>
17661771
DeclTy *createDeclWithClangNode(ClangNode ClangN, AccessLevel access,
17671772
Targs &&... Args) {

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
215215
}
216216

217217
// Create the OpaqueTypeDecl for the result type.
218-
auto opaqueDecl = OpaqueTypeDecl::get(
218+
auto opaqueDecl = OpaqueTypeDecl::create(
219219
originatingDecl, genericParams, parentDC, interfaceSignature,
220220
opaqueReprs);
221221
if (auto originatingSig = originatingDC->getGenericSignatureOfContext()) {

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,11 @@ OTHER(ERROR_FLAG, 155)
215215
OTHER(ABI_ONLY_COUNTERPART, 156)
216216
OTHER(DECL_NAME_REF, 157)
217217

218+
TRAILING_INFO(UNDERLYING_SUBSTITUTION)
218219
TRAILING_INFO(CONDITIONAL_SUBSTITUTION)
219220
TRAILING_INFO(CONDITIONAL_SUBSTITUTION_COND)
220221

221-
OTHER(LIFETIME_DEPENDENCE, 160)
222+
OTHER(LIFETIME_DEPENDENCE, 161)
222223
TRAILING_INFO(INHERITED_PROTOCOLS)
223224

224225
#ifndef DECL_ATTR

0 commit comments

Comments
 (0)