Serialization: Preserve identity of opened generic environments

We used to create a new environment for each opened archetype, which is
incorrect when deserializing a nested type of another opened archetype.
This commit is contained in:
Slava Pestov
2022-08-11 23:44:18 -04:00
parent 7a970367fd
commit b36f37cc72
14 changed files with 165 additions and 51 deletions

View File

@@ -594,6 +594,13 @@ Serializer::addGenericSignatureRef(GenericSignature sig) {
return GenericSignaturesToSerialize.addRef(sig);
}
GenericEnvironmentID
Serializer::addGenericEnvironmentRef(GenericEnvironment *env) {
if (!env)
return 0;
return GenericEnvironmentsToSerialize.addRef(env);
}
SubstitutionMapID
Serializer::addSubstitutionMapRef(SubstitutionMap substitutions) {
return SubstitutionMapsToSerialize.addRef(substitutions);
@@ -878,6 +885,7 @@ void Serializer::writeBlockInfoBlock() {
BLOCK_RECORD(index_block, ENTRY_POINT);
BLOCK_RECORD(index_block, LOCAL_DECL_CONTEXT_OFFSETS);
BLOCK_RECORD(index_block, GENERIC_SIGNATURE_OFFSETS);
BLOCK_RECORD(index_block, GENERIC_ENVIRONMENT_OFFSETS);
BLOCK_RECORD(index_block, SUBSTITUTION_MAP_OFFSETS);
BLOCK_RECORD(index_block, CLANG_TYPE_OFFSETS);
BLOCK_RECORD(index_block, LOCAL_TYPE_DECLS);
@@ -1490,6 +1498,20 @@ void Serializer::writeASTBlockEntity(GenericSignature sig) {
}
}
void Serializer::writeASTBlockEntity(const GenericEnvironment *genericEnv) {
using namespace decls_block;
assert(GenericEnvironmentsToSerialize.hasRef(genericEnv));
auto existentialTypeID = addTypeRef(genericEnv->getOpenedExistentialType());
auto parentSig = genericEnv->getOpenedExistentialParentSignature();
auto parentSigID = addGenericSignatureRef(parentSig);
auto genericEnvAbbrCode = DeclTypeAbbrCodes[GenericEnvironmentLayout::Code];
GenericEnvironmentLayout::emitRecord(Out, ScratchRecord, genericEnvAbbrCode,
existentialTypeID, parentSigID);
}
void Serializer::writeASTBlockEntity(const SubstitutionMap substitutions) {
using namespace decls_block;
assert(substitutions);
@@ -4603,14 +4625,12 @@ public:
void visitOpenedArchetypeType(const OpenedArchetypeType *archetypeTy) {
using namespace decls_block;
auto sig = archetypeTy->getGenericEnvironment()->getGenericSignature();
auto existentialTypeID = S.addTypeRef(archetypeTy->getExistentialType());
auto interfaceTypeID = S.addTypeRef(archetypeTy->getInterfaceType());
auto sigID = S.addGenericSignatureRef(sig);
auto genericEnvID = S.addGenericEnvironmentRef(
archetypeTy->getGenericEnvironment());
unsigned abbrCode = S.DeclTypeAbbrCodes[OpenedArchetypeTypeLayout::Code];
OpenedArchetypeTypeLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode,
existentialTypeID, interfaceTypeID,
sigID);
interfaceTypeID, genericEnvID);
}
void
@@ -5107,6 +5127,7 @@ void Serializer::writeAllDeclsAndTypes() {
registerDeclTypeAbbr<InlinableBodyTextLayout>();
registerDeclTypeAbbr<GenericParamListLayout>();
registerDeclTypeAbbr<GenericSignatureLayout>();
registerDeclTypeAbbr<GenericEnvironmentLayout>();
registerDeclTypeAbbr<RequirementSignatureLayout>();
registerDeclTypeAbbr<SILGenericSignatureLayout>();
registerDeclTypeAbbr<SubstitutionMapLayout>();
@@ -5161,6 +5182,8 @@ void Serializer::writeAllDeclsAndTypes() {
writeASTBlockEntitiesIfNeeded(LocalDeclContextsToSerialize);
wroteSomething |=
writeASTBlockEntitiesIfNeeded(GenericSignaturesToSerialize);
wroteSomething |=
writeASTBlockEntitiesIfNeeded(GenericEnvironmentsToSerialize);
wroteSomething |=
writeASTBlockEntitiesIfNeeded(SubstitutionMapsToSerialize);
wroteSomething |=
@@ -5764,6 +5787,7 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
writeOffsets(Offsets, ClangTypesToSerialize);
writeOffsets(Offsets, LocalDeclContextsToSerialize);
writeOffsets(Offsets, GenericSignaturesToSerialize);
writeOffsets(Offsets, GenericEnvironmentsToSerialize);
writeOffsets(Offsets, SubstitutionMapsToSerialize);
writeOffsets(Offsets, ConformancesToSerialize);
writeOffsets(Offsets, SILLayoutsToSerialize);