Merge pull request #85593 from slavapestov/lazy-opaque-type-decl

Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions
This commit is contained in:
Slava Pestov
2025-11-21 00:43:22 -05:00
committed by GitHub
13 changed files with 362 additions and 183 deletions

View File

@@ -761,6 +761,11 @@ protected:
HasAnyUnavailableDuringLoweringValues : 1
);
SWIFT_INLINE_BITFIELD(OpaqueTypeDecl, GenericTypeDecl, 1,
/// Whether we have lazily-loaded underlying substitutions.
HasLazyUnderlyingSubstitutions : 1
);
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,
/// If the module is compiled as static library.
StaticLibrary : 1,
@@ -3646,7 +3651,8 @@ private:
OpaqueTypeDecl(ValueDecl *NamingDecl, GenericParamList *GenericParams,
DeclContext *DC,
GenericSignature OpaqueInterfaceGenericSignature,
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs,
bool hasLazyUnderlyingSubstitutions);
unsigned getNumOpaqueReturnTypeReprs() const {
return NamingDeclAndHasOpaqueReturnTypeRepr.getInt()
@@ -3658,13 +3664,21 @@ private:
return getNumOpaqueReturnTypeReprs();
}
void loadLazyUnderlyingSubstitutions();
public:
static OpaqueTypeDecl *get(
static OpaqueTypeDecl *create(
ValueDecl *NamingDecl, GenericParamList *GenericParams,
DeclContext *DC,
GenericSignature OpaqueInterfaceGenericSignature,
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
static OpaqueTypeDecl *createDeserialized(
GenericParamList *GenericParams,
DeclContext *DC,
GenericSignature OpaqueInterfaceGenericSignature,
LazyMemberLoader *lazyLoader, uint64_t underlyingSubsData);
ValueDecl *getNamingDecl() const {
return NamingDeclAndHasOpaqueReturnTypeRepr.getPointer();
}
@@ -3720,19 +3734,19 @@ public:
bool typeCheckFunctionBodies=true) const;
void setUniqueUnderlyingTypeSubstitutions(SubstitutionMap subs) {
assert(!UniqueUnderlyingType.has_value() && "resetting underlying type?!");
ASSERT(!Bits.OpaqueTypeDecl.HasLazyUnderlyingSubstitutions);
ASSERT(!UniqueUnderlyingType.has_value() && "resetting underlying type?!");
UniqueUnderlyingType = subs;
}
bool hasConditionallyAvailableSubstitutions() const {
const_cast<OpaqueTypeDecl *>(this)->loadLazyUnderlyingSubstitutions();
return ConditionallyAvailableTypes.has_value();
}
ArrayRef<ConditionallyAvailableSubstitutions *>
getConditionallyAvailableSubstitutions() const {
assert(ConditionallyAvailableTypes);
return ConditionallyAvailableTypes.value();
}
getConditionallyAvailableSubstitutions() const;
void setConditionallyAvailableSubstitutions(
ArrayRef<ConditionallyAvailableSubstitutions *> substitutions);

View File

@@ -63,6 +63,12 @@ public:
uint64_t defaultDefinitionTypeData = 0;
};
class LazyOpaqueTypeData : public LazyContextData {
public:
/// The context data used for loading the underlying type substitution map.
uint64_t underlyingSubsData = 0;
};
/// Context data for protocols.
class LazyProtocolData : public LazyIterableDeclContextData {
public:
@@ -138,6 +144,10 @@ public:
// Returns the target parameter of the `@_specialize` attribute or null.
virtual ValueDecl *loadTargetFunctionDecl(const AbstractSpecializeAttr *attr,
uint64_t contextData) = 0;
/// Loads the underlying type substitution map of an opaque result declaration.
virtual void
finishOpaqueTypeDecl(OpaqueTypeDecl *opaqueDecl, uint64_t contextData) = 0;
};
/// A class that can lazily load conformances from a serialized format.