Skip to content

Commit 6596c74

Browse files
authored
Merge pull request #85684 from slavapestov/lazy-opaque-type-decl-6.3
Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions [6.3]
2 parents 2421cef + e5326e8 commit 6596c74

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
@@ -10810,13 +10810,16 @@ bool AbstractFunctionDecl::isResilient(ModuleDecl *M,
1081010810
OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
1081110811
GenericParamList *GenericParams, DeclContext *DC,
1081210812
GenericSignature OpaqueInterfaceGenericSignature,
10813-
ArrayRef<TypeRepr *>
10814-
OpaqueReturnTypeReprs)
10813+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs,
10814+
bool hasLazyUnderlyingSubstitutions)
1081510815
: GenericTypeDecl(DeclKind::OpaqueType, DC, Identifier(), SourceLoc(), {},
1081610816
GenericParams),
1081710817
NamingDeclAndHasOpaqueReturnTypeRepr(
1081810818
NamingDecl, !OpaqueReturnTypeReprs.empty()),
1081910819
OpaqueInterfaceGenericSignature(OpaqueInterfaceGenericSignature) {
10820+
Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions
10821+
= hasLazyUnderlyingSubstitutions;
10822+
1082010823
// Always implicit.
1082110824
setImplicit();
1082210825

@@ -10829,7 +10832,7 @@ OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
1082910832
OpaqueReturnTypeReprs.end(), getTrailingObjects());
1083010833
}
1083110834

10832-
OpaqueTypeDecl *OpaqueTypeDecl::get(
10835+
OpaqueTypeDecl *OpaqueTypeDecl::create(
1083310836
ValueDecl *NamingDecl, GenericParamList *GenericParams,
1083410837
DeclContext *DC,
1083510838
GenericSignature OpaqueInterfaceGenericSignature,
@@ -10840,7 +10843,33 @@ OpaqueTypeDecl *OpaqueTypeDecl::get(
1084010843
auto mem = ctx.Allocate(size, alignof(OpaqueTypeDecl));
1084110844
return new (mem) OpaqueTypeDecl(
1084210845
NamingDecl, GenericParams, DC, OpaqueInterfaceGenericSignature,
10843-
OpaqueReturnTypeReprs);
10846+
OpaqueReturnTypeReprs, /*hasLazyUnderlyingSubstitutions=*/false);
10847+
}
10848+
10849+
OpaqueTypeDecl *OpaqueTypeDecl::createDeserialized(
10850+
GenericParamList *GenericParams, DeclContext *DC,
10851+
GenericSignature OpaqueInterfaceGenericSignature,
10852+
LazyMemberLoader *lazyLoader, uint64_t underlyingSubsData) {
10853+
bool hasLazyUnderlyingSubstitutions = (underlyingSubsData != 0);
10854+
10855+
ASTContext &ctx = DC->getASTContext();
10856+
auto size = totalSizeToAlloc<TypeRepr *>(0);
10857+
auto mem = ctx.Allocate(size, alignof(OpaqueTypeDecl));
10858+
10859+
// NamingDecl is set later by deserialization
10860+
auto *decl = new (mem) OpaqueTypeDecl(
10861+
/*namingDecl=*/nullptr, GenericParams, DC,
10862+
OpaqueInterfaceGenericSignature, { },
10863+
hasLazyUnderlyingSubstitutions);
10864+
10865+
if (hasLazyUnderlyingSubstitutions) {
10866+
auto &ctx = DC->getASTContext();
10867+
auto *data = static_cast<LazyOpaqueTypeData *>(
10868+
ctx.getOrCreateLazyContextData(decl, lazyLoader));
10869+
data->underlyingSubsData = underlyingSubsData;
10870+
}
10871+
10872+
return decl;
1084410873
}
1084510874

1084610875
bool OpaqueTypeDecl::isOpaqueReturnTypeOf(const Decl *ownerDecl) const {
@@ -10896,16 +10925,41 @@ bool OpaqueTypeDecl::exportUnderlyingType() const {
1089610925
llvm_unreachable("The naming decl is expected to be either an AFD or ASD");
1089710926
}
1089810927

10928+
void OpaqueTypeDecl::loadLazyUnderlyingSubstitutions() {
10929+
if (!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions)
10930+
return;
10931+
10932+
Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions = 0;
10933+
10934+
auto &ctx = getASTContext();
10935+
auto *data = static_cast<LazyOpaqueTypeData *>(
10936+
ctx.getLazyContextData(this));
10937+
ASSERT(data != nullptr);
10938+
10939+
data->loader->finishOpaqueTypeDecl(
10940+
this, data->underlyingSubsData);
10941+
}
10942+
1089910943
std::optional<SubstitutionMap>
1090010944
OpaqueTypeDecl::getUniqueUnderlyingTypeSubstitutions(
1090110945
bool typeCheckFunctionBodies) const {
10946+
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
10947+
1090210948
if (!typeCheckFunctionBodies)
1090310949
return UniqueUnderlyingType;
1090410950

1090510951
return evaluateOrDefault(getASTContext().evaluator,
1090610952
UniqueUnderlyingTypeSubstitutionsRequest{this}, {});
1090710953
}
1090810954

10955+
ArrayRef<OpaqueTypeDecl::ConditionallyAvailableSubstitutions *>
10956+
OpaqueTypeDecl::getConditionallyAvailableSubstitutions() const {
10957+
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
10958+
10959+
assert(ConditionallyAvailableTypes);
10960+
return ConditionallyAvailableTypes.value();
10961+
}
10962+
1090910963
std::optional<unsigned>
1091010964
OpaqueTypeDecl::getAnonymousOpaqueParamOrdinal(TypeRepr *repr) const {
1091110965
assert(NamingDeclAndHasOpaqueReturnTypeRepr.getInt() &&
@@ -10935,7 +10989,8 @@ Identifier OpaqueTypeDecl::getOpaqueReturnTypeIdentifier() const {
1093510989

1093610990
void OpaqueTypeDecl::setConditionallyAvailableSubstitutions(
1093710991
ArrayRef<ConditionallyAvailableSubstitutions *> substitutions) {
10938-
assert(!ConditionallyAvailableTypes &&
10992+
ASSERT(!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions);
10993+
ASSERT(!ConditionallyAvailableTypes &&
1093910994
"resetting conditionally available substitutions?!");
1094010995
ConditionallyAvailableTypes = getASTContext().AllocateCopy(substitutions);
1094110996
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
17651765
llvm_unreachable("unimplemented for ClangImporter");
17661766
}
17671767

1768+
void finishOpaqueTypeDecl(OpaqueTypeDecl *decl,
1769+
uint64_t contextData) override {
1770+
llvm_unreachable("unimplemented for ClangImporter");
1771+
}
1772+
17681773
template <typename DeclTy, typename ...Targs>
17691774
DeclTy *createDeclWithClangNode(ClangNode ClangN, AccessLevel access,
17701775
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)