Skip to content

Commit 7dccef2

Browse files
authored
Merge pull request #65312 from slavapestov/variadic-generics-cherrypicks-5.9
Various variadic generic fixes [5.9]
2 parents e9fe58d + 82f6fff commit 7dccef2

38 files changed

+505
-315
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,6 @@ struct PrintOptions {
293293

294294
bool PrintImplicitAttrs = true;
295295

296-
/// Whether to print the \c each keyword for pack archetypes.
297-
bool PrintExplicitEach = false;
298-
299296
/// Whether to print the \c any keyword for existential
300297
/// types.
301298
bool PrintExplicitAny = false;

lib/AST/ASTMangler.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3156,17 +3156,17 @@ void ASTMangler::appendGenericSignatureParts(
31563156
ArrayRef<CanGenericTypeParamType> params,
31573157
unsigned initialParamDepth,
31583158
ArrayRef<Requirement> requirements) {
3159-
// Mangle the requirements.
3160-
for (const Requirement &reqt : requirements) {
3161-
appendRequirement(reqt, sig);
3162-
}
3163-
31643159
// Mangle which generic parameters are pack parameters.
31653160
for (auto param : params) {
31663161
if (param->isParameterPack())
31673162
appendOpWithGenericParamIndex("Rv", param);
31683163
}
31693164

3165+
// Mangle the requirements.
3166+
for (const Requirement &reqt : requirements) {
3167+
appendRequirement(reqt, sig);
3168+
}
3169+
31703170
if (params.size() == 1 && params[0]->getDepth() == initialParamDepth)
31713171
return appendOperator("l");
31723172

lib/AST/ASTPrinter.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,11 +1732,11 @@ void PrintAST::printSingleDepthOfGenericSignature(
17321732
llvm::interleave(
17331733
genericParams,
17341734
[&](GenericTypeParamType *param) {
1735-
if (param->isParameterPack())
1736-
Printer << "each ";
17371735
if (!subMap.empty()) {
17381736
printType(substParam(param));
17391737
} else if (auto *GP = param->getDecl()) {
1738+
if (param->isParameterPack())
1739+
Printer << "each ";
17401740
Printer.callPrintStructurePre(PrintStructureKind::GenericParameter,
17411741
GP);
17421742
Printer.printName(GP->getName(),
@@ -1835,9 +1835,9 @@ void PrintAST::printSingleDepthOfGenericSignature(
18351835
void PrintAST::printRequirement(const Requirement &req) {
18361836
switch (req.getKind()) {
18371837
case RequirementKind::SameShape:
1838-
Printer << "(repeat (each ";
1838+
Printer << "(repeat (";
18391839
printTransformedType(req.getFirstType());
1840-
Printer << ", each ";
1840+
Printer << ", ";
18411841
printTransformedType(req.getSecondType());
18421842
Printer << ")) : Any";
18431843
return;
@@ -5710,10 +5710,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57105710
if (!Options.PrintExplicitAny)
57115711
return isSimpleUnderPrintOptions(existential->getInstanceType());
57125712
} else if (auto param = dyn_cast<GenericTypeParamType>(T.getPointer())) {
5713-
if (param->isParameterPack() && Options.PrintExplicitEach)
5713+
if (param->isParameterPack())
57145714
return false;
57155715
} else if (auto archetype = dyn_cast<ArchetypeType>(T.getPointer())) {
5716-
if (archetype->isParameterPack() && Options.PrintExplicitEach)
5716+
if (archetype->isParameterPack())
57175717
return false;
57185718
if (Options.PrintForSIL && isa<LocalArchetypeType>(archetype))
57195719
return false;
@@ -6049,11 +6049,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60496049
}
60506050

60516051
void visitPackExpansionType(PackExpansionType *T) {
6052-
PrintOptions innerOptions = Options;
6053-
innerOptions.PrintExplicitEach = true;
6054-
60556052
Printer << "repeat ";
6056-
TypePrinter(Printer, innerOptions).visit(T->getPatternType());
6053+
visit(T->getPatternType());
60576054
}
60586055

60596056
void visitTupleType(TupleType *T) {
@@ -6963,8 +6960,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
69636960
}
69646961

69656962
void printEach() {
6966-
if (Options.PrintExplicitEach)
6967-
Printer << "each ";
6963+
Printer << "each ";
69686964
}
69696965

69706966
void printArchetypeCommon(ArchetypeType *T) {

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,22 +1009,11 @@ Type ConstraintSystem::openOpaqueType(OpaqueTypeArchetypeType *opaque,
10091009
// underlying return type.
10101010
auto opaqueLocator = locator.withPathElement(
10111011
LocatorPathElt::OpenedOpaqueArchetype(opaqueDecl));
1012+
10121013
OpenedTypeMap replacements;
10131014
openGeneric(DC, opaqueDecl->getOpaqueInterfaceGenericSignature(),
10141015
opaqueLocator, replacements);
10151016

1016-
// If there is an outer generic signature, bind the outer parameters based
1017-
// on the substitutions in the opaque type.
1018-
auto subs = opaque->getSubstitutions();
1019-
if (auto genericSig = subs.getGenericSignature()) {
1020-
for (auto *genericParamPtr : genericSig.getGenericParams()) {
1021-
Type genericParam(genericParamPtr);
1022-
addConstraint(
1023-
ConstraintKind::Bind, openType(genericParam, replacements),
1024-
genericParam.subst(subs), opaqueLocator);
1025-
}
1026-
}
1027-
10281017
recordOpenedTypes(opaqueLocatorKey, replacements);
10291018

10301019
return openType(opaque->getInterfaceType(), replacements);
@@ -1773,6 +1762,8 @@ static void bindArchetypesFromContext(
17731762
auto genericSig = parentDC->getGenericSignatureOfContext();
17741763
for (auto *paramTy : genericSig.getGenericParams()) {
17751764
Type contextTy = cs.DC->mapTypeIntoContext(paramTy);
1765+
if (paramTy->isParameterPack())
1766+
contextTy = PackType::getSingletonPackExpansion(contextTy);
17761767
bindPrimaryArchetype(paramTy, contextTy);
17771768
}
17781769

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4626,7 +4626,8 @@ NeverNullType TypeResolver::resolvePackElement(PackElementTypeRepr *repr,
46264626
return packReference;
46274627
}
46284628

4629-
if (!options.contains(TypeResolutionFlags::AllowPackReferences)) {
4629+
if (!options.contains(TypeResolutionFlags::AllowPackReferences) &&
4630+
!options.contains(TypeResolutionFlags::SILMode)) {
46304631
ctx.Diags.diagnose(repr->getLoc(),
46314632
diag::pack_reference_outside_expansion,
46324633
packReference);

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ OTHER(EXPANDED_MACRO_REPLACEMENTS, 132)
190190
OTHER(NORMAL_PROTOCOL_CONFORMANCE, 141)
191191
OTHER(SPECIALIZED_PROTOCOL_CONFORMANCE, 142)
192192
OTHER(INHERITED_PROTOCOL_CONFORMANCE, 143)
193-
// 144 is unused; was INVALID_PROTOCOL_CONFORMANCE
193+
OTHER(PACK_CONFORMANCE, 144)
194194

195195
OTHER(SIL_LAYOUT, 145)
196196
// 146 is unused; was NORMAL_PROTOCOL_CONFORMANCE_ID

lib/Serialization/Deserialization.cpp

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/Initializer.h"
2727
#include "swift/AST/MacroDefinition.h"
2828
#include "swift/AST/NameLookupRequests.h"
29+
#include "swift/AST/PackConformance.h"
2930
#include "swift/AST/ParameterList.h"
3031
#include "swift/AST/Pattern.h"
3132
#include "swift/AST/PrettyStackTrace.h"
@@ -498,6 +499,9 @@ class ProtocolConformanceDeserializer {
498499
ModuleFile::Serialized<ProtocolConformance *> &entry);
499500
Expected<ProtocolConformance *>
500501
readNormalProtocolConformanceXRef(ArrayRef<uint64_t> data);
502+
503+
Expected<PackConformance *>
504+
read(ModuleFile::Serialized<PackConformance *> &entry);
501505
};
502506
} // end namespace swift
503507

@@ -761,58 +765,134 @@ ProtocolConformanceDeserializer::readNormalProtocolConformance(
761765
return conformance;
762766
}
763767

768+
Expected<PackConformance*>
769+
ProtocolConformanceDeserializer::read(
770+
ModuleFile::Serialized<PackConformance *> &conformanceEntry) {
771+
using namespace decls_block;
772+
773+
SmallVector<uint64_t, 16> scratch;
774+
775+
llvm::BitstreamEntry entry =
776+
MF.fatalIfUnexpected(MF.DeclTypeCursor.advance());
777+
778+
if (entry.Kind != llvm::BitstreamEntry::Record) {
779+
// We don't know how to serialize types represented by sub-blocks.
780+
return MF.diagnoseFatal();
781+
}
782+
783+
StringRef blobData;
784+
unsigned kind = MF.fatalIfUnexpected(
785+
MF.DeclTypeCursor.readRecord(entry.ID, scratch, &blobData));
786+
assert(blobData.empty());
787+
788+
if (kind != decls_block::PACK_CONFORMANCE)
789+
return MF.diagnoseFatal(llvm::make_error<InvalidRecordKindError>(kind));
790+
791+
TypeID patternTypeID;
792+
DeclID protocolID;
793+
ArrayRef<uint64_t> patternConformanceIDs;
794+
PackConformanceLayout::readRecord(scratch,
795+
patternTypeID, protocolID,
796+
patternConformanceIDs);
797+
798+
auto patternTypeOrError = MF.getTypeChecked(patternTypeID);
799+
if (!patternTypeOrError)
800+
return patternTypeOrError.takeError();
801+
auto patternType = patternTypeOrError.get();
802+
803+
auto protocolOrError = MF.getDeclChecked(protocolID);
804+
if (!protocolOrError)
805+
return protocolOrError.takeError();
806+
auto *protocol = protocolOrError.get();
807+
808+
PrettyStackTraceType trace(MF.getAssociatedModule()->getASTContext(),
809+
"reading pack conformance for",
810+
patternType);
811+
812+
SmallVector<ProtocolConformanceRef, 4> patternConformances;
813+
for (auto confID : patternConformanceIDs) {
814+
auto confOrError = MF.getConformanceChecked(confID);
815+
if (!confOrError)
816+
return confOrError.takeError();
817+
patternConformances.push_back(confOrError.get());
818+
}
819+
820+
auto conformance =
821+
PackConformance::get(patternType->castTo<PackType>(),
822+
cast<ProtocolDecl>(protocol),
823+
patternConformances);
824+
return conformance;
825+
}
826+
764827
ProtocolConformanceRef
765-
ModuleFile::getConformance(ProtocolConformanceID id,
766-
GenericEnvironment *genericEnv) {
767-
auto conformance = getConformanceChecked(id, genericEnv);
828+
ModuleFile::getConformance(ProtocolConformanceID id) {
829+
auto conformance = getConformanceChecked(id);
768830
if (!conformance)
769831
fatal(conformance.takeError());
770832
return conformance.get();
771833
}
772834

773835
Expected<ProtocolConformanceRef>
774-
ModuleFile::getConformanceChecked(ProtocolConformanceID conformanceID,
775-
GenericEnvironment *genericEnv) {
836+
ModuleFile::getConformanceChecked(ProtocolConformanceID conformanceID) {
776837
using namespace decls_block;
777838

778839
if (conformanceID == 0) return ProtocolConformanceRef::forInvalid();
779840

780-
// If the low bit is sit, this is an abstract conformance.
781-
if ((conformanceID & 1) == 0) {
782-
auto protocolID = conformanceID >> 1;
841+
switch (conformanceID & SerializedProtocolConformanceKind::Mask) {
842+
case SerializedProtocolConformanceKind::Abstract: {
843+
auto protocolID = conformanceID >> SerializedProtocolConformanceKind::Shift;
783844
auto maybeProtocol = getDeclChecked(protocolID);
784845
if (!maybeProtocol)
785846
return maybeProtocol.takeError();
786847
auto proto = cast<ProtocolDecl>(maybeProtocol.get());
787848
return ProtocolConformanceRef(proto);
788849
}
789850

790-
// Otherwise, it's a concrete conformance.
791-
auto conformanceIndex = (conformanceID >> 1) - 1;
792-
assert(conformanceIndex < Conformances.size() && "invalid conformance ID");
793-
auto &conformanceOrOffset = Conformances[conformanceIndex];
794-
if (!conformanceOrOffset.isComplete()) {
795-
BCOffsetRAII restoreOffset(DeclTypeCursor);
796-
if (auto error = diagnoseFatalIfNotSuccess(
797-
DeclTypeCursor.JumpToBit(conformanceOrOffset)))
798-
return std::move(error);
851+
case SerializedProtocolConformanceKind::Concrete: {
852+
auto conformanceIndex = (conformanceID >> SerializedProtocolConformanceKind::Shift) - 1;
853+
assert(conformanceIndex < Conformances.size() && "invalid conformance ID");
854+
auto &conformanceOrOffset = Conformances[conformanceIndex];
855+
if (!conformanceOrOffset.isComplete()) {
856+
BCOffsetRAII restoreOffset(DeclTypeCursor);
857+
if (auto error = diagnoseFatalIfNotSuccess(
858+
DeclTypeCursor.JumpToBit(conformanceOrOffset)))
859+
return std::move(error);
799860

800-
auto result =
801-
ProtocolConformanceDeserializer(*this).read(conformanceOrOffset);
802-
if (!result)
803-
return result.takeError();
861+
auto result =
862+
ProtocolConformanceDeserializer(*this).read(conformanceOrOffset);
863+
if (!result)
864+
return result.takeError();
804865

805-
conformanceOrOffset = result.get();
866+
conformanceOrOffset = result.get();
867+
}
868+
auto conformance = conformanceOrOffset.get();
869+
return ProtocolConformanceRef(conformance);
806870
}
807-
auto conformance = conformanceOrOffset.get();
808-
if (!genericEnv || !conformance->getType()->hasTypeParameter())
871+
872+
case SerializedProtocolConformanceKind::Pack: {
873+
auto conformanceIndex = (conformanceID >> SerializedProtocolConformanceKind::Shift) - 1;
874+
assert(conformanceIndex < PackConformances.size() && "invalid pack conformance ID");
875+
auto &conformanceOrOffset = PackConformances[conformanceIndex];
876+
if (!conformanceOrOffset.isComplete()) {
877+
BCOffsetRAII restoreOffset(DeclTypeCursor);
878+
if (auto error = diagnoseFatalIfNotSuccess(
879+
DeclTypeCursor.JumpToBit(conformanceOrOffset)))
880+
return std::move(error);
881+
882+
auto result =
883+
ProtocolConformanceDeserializer(*this).read(conformanceOrOffset);
884+
if (!result)
885+
return result.takeError();
886+
887+
conformanceOrOffset = result.get();
888+
}
889+
auto conformance = conformanceOrOffset.get();
809890
return ProtocolConformanceRef(conformance);
891+
}
810892

811-
// If we have a generic environment, map the conformance into context.
812-
auto mappedConformance =
813-
genericEnv->mapConformanceRefIntoContext(conformance->getType(),
814-
ProtocolConformanceRef(conformance));
815-
return mappedConformance.second;
893+
default:
894+
llvm_unreachable("Invalid conformance");
895+
}
816896
}
817897

818898
GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {

lib/Serialization/DeserializeSIL.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,11 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
12841284
SILInstHasSymbolLayout::readRecord(scratch, ValID, ListOfValues);
12851285
RawOpCode = (unsigned)SILInstructionKind::HasSymbolInst;
12861286
break;
1287+
case SIL_OPEN_PACK_ELEMENT:
1288+
SILOpenPackElementLayout::readRecord(scratch, Attr,
1289+
TyID, TyCategory, ValID);
1290+
RawOpCode = (unsigned)SILInstructionKind::OpenPackElementInst;
1291+
break;
12871292
case SIL_PACK_ELEMENT_GET:
12881293
SILPackElementGetLayout::readRecord(scratch, RawOpCode,
12891294
TyID, TyCategory,
@@ -1424,7 +1429,7 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
14241429
break;
14251430
}
14261431
case SILInstructionKind::OpenPackElementInst: {
1427-
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand");
1432+
assert(RecordKind == SIL_OPEN_PACK_ELEMENT && "Layout should be OpenPackElement");
14281433
auto index = getLocalValue(ValID,
14291434
getSILType(MF->getType(TyID), (SILValueCategory) TyCategory, Fn));
14301435
auto env = MF->getGenericEnvironmentChecked(Attr);

lib/Serialization/ModuleFile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ ModuleFile::ModuleFile(std::shared_ptr<const ModuleFileSharedCore> core)
110110
allocateBuffer(Decls, core->Decls);
111111
allocateBuffer(LocalDeclContexts, core->LocalDeclContexts);
112112
allocateBuffer(Conformances, core->Conformances);
113+
allocateBuffer(PackConformances, core->PackConformances);
113114
allocateBuffer(SILLayouts, core->SILLayouts);
114115
allocateBuffer(Types, core->Types);
115116
allocateBuffer(ClangTypes, core->ClangTypes);

lib/Serialization/ModuleFile.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ class ModuleFile
254254
/// Protocol conformances referenced by this module.
255255
MutableArrayRef<Serialized<ProtocolConformance *>> Conformances;
256256

257+
/// Pack conformances referenced by this module.
258+
MutableArrayRef<Serialized<PackConformance *>> PackConformances;
259+
257260
/// SILLayouts referenced by this module.
258261
MutableArrayRef<Serialized<SILLayout *>> SILLayouts;
259262

@@ -986,13 +989,11 @@ class ModuleFile
986989

987990
/// Returns the protocol conformance for the given ID.
988991
ProtocolConformanceRef
989-
getConformance(serialization::ProtocolConformanceID id,
990-
GenericEnvironment *genericEnv = nullptr);
992+
getConformance(serialization::ProtocolConformanceID id);
991993

992994
/// Returns the protocol conformance for the given ID.
993995
llvm::Expected<ProtocolConformanceRef>
994-
getConformanceChecked(serialization::ProtocolConformanceID id,
995-
GenericEnvironment *genericEnv = nullptr);
996+
getConformanceChecked(serialization::ProtocolConformanceID id);
996997

997998
/// Read a SILLayout from the given cursor.
998999
SILLayout *readSILLayout(llvm::BitstreamCursor &Cursor);

0 commit comments

Comments
 (0)