Skip to content

Commit 7ee83a0

Browse files
committed
Serialization: Round-trip the RequirementMachine's ProtocolTypeAlias records
1 parent 530bee5 commit 7ee83a0

File tree

9 files changed

+117
-18
lines changed

9 files changed

+117
-18
lines changed

include/swift/AST/LazyResolver.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#ifndef SWIFT_AST_LAZYRESOLVER_H
1818
#define SWIFT_AST_LAZYRESOLVER_H
1919

20-
#include "swift/AST/ProtocolConformanceRef.h"
2120
#include "llvm/ADT/PointerEmbeddedInt.h"
2221

2322
namespace swift {
@@ -32,6 +31,7 @@ class NominalTypeDecl;
3231
class NormalProtocolConformance;
3332
class ProtocolConformance;
3433
class ProtocolDecl;
34+
class ProtocolTypeAlias;
3535
class TypeDecl;
3636
class ValueDecl;
3737
class VarDecl;
@@ -99,7 +99,8 @@ class alignas(void*) LazyMemberLoader {
9999
/// Loads the requirement signature for a protocol.
100100
virtual void
101101
loadRequirementSignature(const ProtocolDecl *proto, uint64_t contextData,
102-
SmallVectorImpl<Requirement> &requirements) = 0;
102+
SmallVectorImpl<Requirement> &requirements,
103+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases) = 0;
103104

104105
/// Loads the associated types of a protocol.
105106
virtual void

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8602,12 +8602,13 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
86028602
auto contextData = static_cast<LazyProtocolData *>(
86038603
ctx.getOrCreateLazyContextData(proto, nullptr));
86048604

8605-
SmallVector<Requirement, 8> requirements;
8605+
SmallVector<Requirement, 2> requirements;
8606+
SmallVector<ProtocolTypeAlias, 2> typeAliases;
86068607
contextData->loader->loadRequirementSignature(
8607-
proto, contextData->requirementSignatureData, requirements);
8608-
if (requirements.empty())
8609-
return RequirementSignature();
8610-
return RequirementSignature(ctx.AllocateCopy(requirements), None);
8608+
proto, contextData->requirementSignatureData,
8609+
requirements, typeAliases);
8610+
return RequirementSignature(ctx.AllocateCopy(requirements),
8611+
ctx.AllocateCopy(typeAliases));
86118612
}
86128613

86138614
auto buildViaGSB = [&]() {

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/ForeignErrorConvention.h"
2727
#include "swift/AST/LazyResolver.h"
2828
#include "swift/AST/Module.h"
29+
#include "swift/AST/RequirementSignature.h"
2930
#include "swift/AST/Type.h"
3031
#include "swift/Basic/FileTypes.h"
3132
#include "swift/Basic/StringExtras.h"
@@ -1516,7 +1517,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
15161517
}
15171518

15181519
void loadRequirementSignature(const ProtocolDecl *decl, uint64_t contextData,
1519-
SmallVectorImpl<Requirement> &reqs) override {
1520+
SmallVectorImpl<Requirement> &reqs,
1521+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases) override {
15201522
llvm_unreachable("unimplemented for ClangImporter");
15211523
}
15221524

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ DECL(OPAQUE_TYPE)
127127
DECL(PATTERN_BINDING)
128128
DECL(PROTOCOL)
129129
TRAILING_INFO(DEFAULT_WITNESS_TABLE)
130+
TRAILING_INFO(PROTOCOL_TYPEALIAS)
130131
TRAILING_INFO(ASSOCIATED_TYPE)
131132
DECL(PREFIX_OPERATOR)
132133
DECL(POSTFIX_OPERATOR)

lib/Serialization/Deserialization.cpp

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,53 @@ llvm::Error ModuleFile::readGenericRequirementsChecked(
889889
return llvm::Error::success();
890890
}
891891

892+
void ModuleFile::readRequirementSignature(
893+
SmallVectorImpl<Requirement> &requirements,
894+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases,
895+
llvm::BitstreamCursor &Cursor) {
896+
readGenericRequirements(requirements, Cursor);
897+
898+
using namespace decls_block;
899+
900+
BCOffsetRAII lastRecordOffset(Cursor);
901+
SmallVector<uint64_t, 8> scratch;
902+
StringRef blobData;
903+
904+
while (true) {
905+
lastRecordOffset.reset();
906+
bool shouldContinue = true;
907+
908+
llvm::BitstreamEntry entry =
909+
fatalIfUnexpected(Cursor.advance(AF_DontPopBlockAtEnd));
910+
if (entry.Kind != llvm::BitstreamEntry::Record)
911+
break;
912+
913+
scratch.clear();
914+
unsigned recordID = fatalIfUnexpected(
915+
Cursor.readRecord(entry.ID, scratch, &blobData));
916+
switch (recordID) {
917+
case PROTOCOL_TYPEALIAS: {
918+
uint64_t rawName;
919+
uint64_t rawTypeID;
920+
ProtocolTypeAliasLayout::readRecord(scratch, rawName, rawTypeID);
921+
922+
auto name = getIdentifier(rawName);
923+
auto underlyingType = getType(rawTypeID);
924+
925+
typeAliases.emplace_back(name, underlyingType);
926+
break;
927+
}
928+
default:
929+
// This record is not part of the protocol requirement signature.
930+
shouldContinue = false;
931+
break;
932+
}
933+
934+
if (!shouldContinue)
935+
break;
936+
}
937+
}
938+
892939
void ModuleFile::readAssociatedTypes(
893940
SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
894941
llvm::BitstreamCursor &Cursor) {
@@ -919,8 +966,10 @@ void ModuleFile::readAssociatedTypes(
919966
}
920967
}
921968

922-
/// Advances past any records that might be part of a requirement signature.
923-
static llvm::Error skipGenericRequirements(llvm::BitstreamCursor &Cursor) {
969+
/// Advances past any records that might be part of a protocol requirement
970+
/// signature, which consists of generic requirements together with protocol
971+
/// typealias records.
972+
static llvm::Error skipRequirementSignature(llvm::BitstreamCursor &Cursor) {
924973
using namespace decls_block;
925974

926975
BCOffsetRAII lastRecordOffset(Cursor);
@@ -940,6 +989,7 @@ static llvm::Error skipGenericRequirements(llvm::BitstreamCursor &Cursor) {
940989
switch (maybeRecordID.get()) {
941990
case GENERIC_REQUIREMENT:
942991
case LAYOUT_REQUIREMENT:
992+
case PROTOCOL_TYPEALIAS:
943993
break;
944994

945995
default:
@@ -3611,7 +3661,7 @@ class DeclDeserializer {
36113661

36123662
proto->setLazyRequirementSignature(&MF,
36133663
MF.DeclTypeCursor.GetCurrentBitNo());
3614-
if (llvm::Error Err = skipGenericRequirements(MF.DeclTypeCursor))
3664+
if (llvm::Error Err = skipRequirementSignature(MF.DeclTypeCursor))
36153665
MF.fatal(std::move(Err));
36163666

36173667
proto->setLazyAssociatedTypeMembers(&MF,
@@ -6755,10 +6805,11 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
67556805

67566806
void ModuleFile::loadRequirementSignature(const ProtocolDecl *decl,
67576807
uint64_t contextData,
6758-
SmallVectorImpl<Requirement> &reqs) {
6808+
SmallVectorImpl<Requirement> &reqs,
6809+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases) {
67596810
BCOffsetRAII restoreOffset(DeclTypeCursor);
67606811
fatalIfNotSuccess(DeclTypeCursor.JumpToBit(contextData));
6761-
readGenericRequirements(reqs, DeclTypeCursor);
6812+
readRequirementSignature(reqs, typeAliases, DeclTypeCursor);
67626813
}
67636814

67646815
void ModuleFile::loadAssociatedTypes(const ProtocolDecl *decl,

lib/Serialization/ModuleFile.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ class ModuleFile
398398
readGenericRequirementsChecked(SmallVectorImpl<Requirement> &requirements,
399399
llvm::BitstreamCursor &Cursor);
400400

401+
/// Read the requirement signature of a protocol, which consists of a list of
402+
/// generic requirements and a list of protocol typealias records.
403+
void readRequirementSignature(SmallVectorImpl<Requirement> &requirements,
404+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases,
405+
llvm::BitstreamCursor &Cursor);
406+
401407
/// Read a list of associated type declarations in a protocol.
402408
void readAssociatedTypes(SmallVectorImpl<AssociatedTypeDecl *> &assocTypes,
403409
llvm::BitstreamCursor &Cursor);
@@ -728,7 +734,8 @@ class ModuleFile
728734

729735
void
730736
loadRequirementSignature(const ProtocolDecl *proto, uint64_t contextData,
731-
SmallVectorImpl<Requirement> &requirements) override;
737+
SmallVectorImpl<Requirement> &requirements,
738+
SmallVectorImpl<ProtocolTypeAlias> &typeAliases) override;
732739

733740
void
734741
loadAssociatedTypes(const ProtocolDecl *proto, uint64_t contextData,

lib/Serialization/ModuleFormat.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 668; // @_nonSendable fix
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 669; // RequirementMachine protocol typealiases
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1654,6 +1654,12 @@ namespace decls_block {
16541654
BCVBR<8> // alignment
16551655
>;
16561656

1657+
using ProtocolTypeAliasLayout = BCRecordLayout<
1658+
PROTOCOL_TYPEALIAS,
1659+
IdentifierIDField, // name
1660+
TypeIDField // underlying type
1661+
>;
1662+
16571663
using AssociatedTypeLayout = BCRecordLayout<
16581664
ASSOCIATED_TYPE,
16591665
DeclIDField // associated type decl

lib/Serialization/Serialization.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,23 @@ void Serializer::writeAssociatedTypes(ArrayRef<AssociatedTypeDecl *> assocTypes,
14181418
}
14191419
}
14201420

1421+
void Serializer::writeRequirementSignature(
1422+
const RequirementSignature &requirementSig,
1423+
const std::array<unsigned, 256> &abbrCodes) {
1424+
writeGenericRequirements(requirementSig.getRequirements(), abbrCodes);
1425+
1426+
using namespace decls_block;
1427+
1428+
auto protocolTypeAliasAbbrCode = abbrCodes[ProtocolTypeAliasLayout::Code];
1429+
1430+
for (const auto &typeAlias : requirementSig.getTypeAliases()) {
1431+
ProtocolTypeAliasLayout::emitRecord(
1432+
Out, ScratchRecord, protocolTypeAliasAbbrCode,
1433+
addDeclBaseNameRef(typeAlias.getName()),
1434+
addTypeRef(typeAlias.getUnderlyingType()));
1435+
}
1436+
}
1437+
14211438
void Serializer::writeASTBlockEntity(GenericSignature sig) {
14221439
using namespace decls_block;
14231440

@@ -3633,14 +3650,20 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
36333650
dependencyTypes.insert(elementType);
36343651
}
36353652

3636-
for (Requirement req : proto->getRequirementSignature().getRequirements()) {
3653+
auto requirementSig = proto->getRequirementSignature();
3654+
for (Requirement req : requirementSig.getRequirements()) {
36373655
// Requirements can be cyclic, so for now filter out any requirements
36383656
// from elsewhere in the module. This isn't perfect---something else in
36393657
// the module could very well fail to compile for its own reasons---but
36403658
// it's better than nothing.
36413659
collectDependenciesFromRequirement(dependencyTypes, req,
36423660
/*excluding*/S.M);
36433661
}
3662+
for (ProtocolTypeAlias typeAlias : requirementSig.getTypeAliases()) {
3663+
collectDependenciesFromType(dependencyTypes,
3664+
typeAlias.getUnderlyingType(),
3665+
/*excluding*/S.M);
3666+
}
36443667

36453668
for (Type ty : dependencyTypes)
36463669
inheritedAndDependencyTypes.push_back(S.addTypeRef(ty));
@@ -3660,8 +3683,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
36603683
inheritedAndDependencyTypes);
36613684

36623685
writeGenericParams(proto->getGenericParams());
3663-
S.writeGenericRequirements(
3664-
proto->getRequirementSignature().getRequirements(), S.DeclTypeAbbrCodes);
3686+
S.writeRequirementSignature(
3687+
proto->getRequirementSignature(), S.DeclTypeAbbrCodes);
36653688
S.writeAssociatedTypes(
36663689
proto->getAssociatedTypeMembers(), S.DeclTypeAbbrCodes);
36673690
writeMembers(id, proto->getAllMembers(), true);
@@ -4958,6 +4981,7 @@ void Serializer::writeAllDeclsAndTypes() {
49584981
registerDeclTypeAbbr<OpaqueTypeLayout>();
49594982
registerDeclTypeAbbr<PatternBindingLayout>();
49604983
registerDeclTypeAbbr<ProtocolLayout>();
4984+
registerDeclTypeAbbr<ProtocolTypeAliasLayout>();
49614985
registerDeclTypeAbbr<AssociatedTypeLayout>();
49624986
registerDeclTypeAbbr<DefaultWitnessTableLayout>();
49634987
registerDeclTypeAbbr<PrefixOperatorLayout>();

lib/Serialization/Serialization.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Serialization/SerializationOptions.h"
2222
#include "swift/Subsystems.h"
2323
#include "swift/AST/Identifier.h"
24+
#include "swift/AST/RequirementSignature.h"
2425
#include "swift/Basic/LLVM.h"
2526
#include "llvm/ADT/MapVector.h"
2627
#include <array>
@@ -539,6 +540,11 @@ class Serializer : public SerializerBase {
539540
void writeGenericRequirements(ArrayRef<Requirement> requirements,
540541
const std::array<unsigned, 256> &abbrCodes);
541542

543+
/// Writes a protocol's requirement signature, consisting of a list of
544+
/// generic requirements and a list of protocol typealias records.
545+
void writeRequirementSignature(const RequirementSignature &requirementSig,
546+
const std::array<unsigned, 256> &abbrCodes);
547+
542548
/// Writes a protocol's associated type table.
543549
void writeAssociatedTypes(ArrayRef<AssociatedTypeDecl *> assocTypes,
544550
const std::array<unsigned, 256> &abbrCodes);

0 commit comments

Comments
 (0)