mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Serialization: Lazily deserialize OpaqueTypeDecl's underlying substitutions
We need to serialize the underlying type substitution map for an inlinable function. However, there is no reason to deserialize it eagerly, since doing so can lead to cycles. It is better for correctness and performance to only deserialize it when needed. Technically this fixes a regression from #84299, but the actual problem was there all along, it was just exposed by my change on a specific project. Fixes rdar://163301203.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user