diff --git a/include/swift/AST/TypeDifferenceVisitor.h b/include/swift/AST/TypeDifferenceVisitor.h index b3164132002..d3332060a5b 100644 --- a/include/swift/AST/TypeDifferenceVisitor.h +++ b/include/swift/AST/TypeDifferenceVisitor.h @@ -149,6 +149,11 @@ public: return asImpl().visit(type1.getPatternType(), type2.getPatternType()); } + bool visitPackElementType(CanPackElementType type1, + CanPackElementType type2) { + return asImpl().visit(type1.getPackType(), type2.getPackType()); + } + bool visitTupleType(CanTupleType type1, CanTupleType type2) { return visitComponentArray(type1, type2, type1->getElements(), type2->getElements()); diff --git a/include/swift/AST/TypeMatcher.h b/include/swift/AST/TypeMatcher.h index 65ffcf1d800..8f3e7ca1c3e 100644 --- a/include/swift/AST/TypeMatcher.h +++ b/include/swift/AST/TypeMatcher.h @@ -202,6 +202,18 @@ class TypeMatcher { return mismatch(firstPE.getPointer(), secondType, sugaredFirstType); } + bool visitPackElementType(CanPackElementType firstElement, Type secondType, + Type sugaredFirstType) { + if (auto secondElement = secondType->getAs()) { + return this->visit(firstElement.getPackType(), + secondElement->getPackType(), + sugaredFirstType->castTo() + ->getPackType()); + } + + return mismatch(firstElement.getPointer(), secondType, sugaredFirstType); + } + bool visitReferenceStorageType(CanReferenceStorageType firstStorage, Type secondType, Type sugaredFirstType) { if (firstStorage->getKind() == secondType->getDesugaredType()->getKind()) { diff --git a/include/swift/AST/TypeNodes.def b/include/swift/AST/TypeNodes.def index 8389cb89455..3e21d29073a 100644 --- a/include/swift/AST/TypeNodes.def +++ b/include/swift/AST/TypeNodes.def @@ -186,6 +186,7 @@ TYPE(LValue, Type) TYPE(InOut, Type) TYPE(Pack, Type) TYPE(PackExpansion, Type) +TYPE(PackElement, Type) UNCHECKED_TYPE(TypeVariable, Type) ABSTRACT_SUGARED_TYPE(Sugar, Type) SUGARED_TYPE(Paren, SugarType) diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index dd7b11b0a82..6ec8151bd05 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -6999,13 +6999,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type) } END_CAN_TYPE_WRAPPER(PackExpansionType, Type) - inline CanTypeWrapper CanPackType::unwrapSingletonPackExpansion() const { return CanPackExpansionType( getPointer()->unwrapSingletonPackExpansion()); } +/// Represents a reference to a pack from an outer expansion. This comes up +/// after substitution. For example, given these declarations: +/// +/// typealias A = (repeat (each T, U)) +/// typealias B = (repeat A) +/// +/// Naively substituting replacing {T := repeat each X, U := each Y} in the +/// underlying type of A would give us: +/// +/// '(repeat (repeat (each X, each Y)))' +/// +/// However, this is wrong; we're not expanding X and Y in parallel (they +/// might not even have the same shape). Instead, we're expanding X, and +/// then on each iteration, expanding Y. +/// +/// If we annotate each 'repeat' and its corresponding 'each', we instead see +/// that the above should give us: +/// +/// '(repeat[1] (repeat[0] (each[0], each[1] U)))' +/// +/// We number PackExpansionTypes from the innermost one outwards, assigning +/// a level of 0 to the innermost one. Then, a PackElementType represents a +/// reference to a parameter pack from an expansion with level > 0. +class PackElementType : public TypeBase, public llvm::FoldingSetNode { + friend class ASTContext; + + Type packType; + unsigned level; + + PackElementType(Type packType, unsigned level, + RecursiveTypeProperties properties, + const ASTContext *ctx); + +public: + static PackElementType *get(Type packType, unsigned level); + + Type getPackType() const { return packType; } + + unsigned getLevel() const { return level; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getPackType(), getLevel()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, Type packType, unsigned level); + + // Implement isa/cast/dyncast/etc. + static bool classof(const TypeBase *T) { + return T->getKind() == TypeKind::PackElement; + } +}; +BEGIN_CAN_TYPE_WRAPPER(PackElementType, Type) + static CanPackElementType get(CanType pack); + + CanType getPackType() const { + return CanType(getPointer()->getPackType()); + } +END_CAN_TYPE_WRAPPER(PackElementType, Type) + /// getASTContext - Return the ASTContext that this type belongs to. inline ASTContext &TypeBase::getASTContext() const { // If this type is canonical, it has the ASTContext in it. diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index f8e48af109d..cc6751ff993 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -241,6 +241,7 @@ NODE(Pack) NODE(SILPackDirect) NODE(SILPackIndirect) NODE(PackExpansion) +NODE(PackElement) NODE(Type) CONTEXT_NODE(TypeSymbolicReference) CONTEXT_NODE(TypeAlias) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 18b6185367b..afe9fba56f9 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -416,6 +416,7 @@ struct ASTContext::Implementation { llvm::FoldingSet TupleTypes; llvm::FoldingSet PackTypes; llvm::FoldingSet PackExpansionTypes; + llvm::FoldingSet PackElementTypes; llvm::DenseMap, MetatypeType*> MetatypeTypes; llvm::DenseMap, @@ -3317,6 +3318,47 @@ PackType *PackType::getEmpty(const ASTContext &C) { return cast(CanType(C.TheEmptyPackType)); } +PackElementType::PackElementType(Type packType, unsigned level, + RecursiveTypeProperties properties, + const ASTContext *canCtx) + : TypeBase(TypeKind::PackElement, canCtx, properties), + packType(packType), level(level) { + assert(packType->isParameterPack() || + packType->is() || + packType->is()); + assert(level > 0); +} + +PackElementType *PackElementType::get(Type packType, unsigned level) { + auto properties = packType->getRecursiveProperties(); + auto arena = getArena(properties); + + auto &context = packType->getASTContext(); + llvm::FoldingSetNodeID id; + PackElementType::Profile(id, packType, level); + + void *insertPos; + if (PackElementType *elementType = + context.getImpl().getArena(arena) + .PackElementTypes.FindNodeOrInsertPos(id, insertPos)) + return elementType; + + const ASTContext *canCtx = packType->isCanonical() + ? &context : nullptr; + PackElementType *elementType = + new (context, arena) PackElementType(packType, level, properties, + canCtx); + context.getImpl().getArena(arena).PackElementTypes.InsertNode(elementType, + insertPos); + return elementType; +} + +void PackElementType::Profile(llvm::FoldingSetNodeID &ID, + Type packType, unsigned level) { + ID.AddPointer(packType.getPointer()); + ID.AddInteger(level); +} + CanPackType CanPackType::get(const ASTContext &C, ArrayRef elements) { SmallVector ncElements(elements.begin(), elements.end()); return CanPackType(PackType::get(C, ncElements)); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 2f5aa8b9e61..c7fa382e740 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3873,6 +3873,13 @@ namespace { PrintWithColorRAII(OS, ParenthesisColor) << ')'; } + void visitPackElementType(PackElementType *T, StringRef label) { + printCommon(label, "element_type"); + printField("level", T->getLevel()); + printRec("pack", T->getPackType()); + PrintWithColorRAII(OS, ParenthesisColor) << ')'; + } + void visitParenType(ParenType *T, StringRef label) { printCommon(label, "paren_type"); printRec(T->getUnderlyingType()); diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 8bb9e280890..b414ad659bb 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1285,6 +1285,15 @@ void ASTMangler::appendType(Type type, GenericSignature sig, return; } + case TypeKind::PackElement: { + auto elementType = cast(tybase); + appendType(elementType->getPackType(), sig, forDecl); + + // FIXME: append expansion depth + + return; + } + case TypeKind::Pack: { auto packTy = cast(tybase); diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 4910011645b..38c75481bcb 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -6073,6 +6073,11 @@ public: visit(T->getPatternType()); } + void visitPackElementType(PackElementType *T) { + Printer << "@level(" << T->getLevel() << ") "; + visit(T->getPackType()); + } + void visitTupleType(TupleType *T) { Printer.callPrintStructurePre(PrintStructureKind::TupleType); SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); }; diff --git a/lib/AST/ExistentialGeneralization.cpp b/lib/AST/ExistentialGeneralization.cpp index a49da511cd5..325763e26a5 100644 --- a/lib/AST/ExistentialGeneralization.cpp +++ b/lib/AST/ExistentialGeneralization.cpp @@ -158,6 +158,7 @@ private: NO_PRESERVABLE_STRUCTURE(Module) NO_PRESERVABLE_STRUCTURE(Pack) NO_PRESERVABLE_STRUCTURE(PackExpansion) + NO_PRESERVABLE_STRUCTURE(PackElement) #undef NO_PRESERVABLE_STRUCTURE // These types simply shouldn't appear in types that we generalize at all. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 33c534b0016..2b34ff5c6b4 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -292,6 +292,7 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig, case TypeKind::SILToken: case TypeKind::Pack: case TypeKind::PackExpansion: + case TypeKind::PackElement: case TypeKind::SILPack: #define REF_STORAGE(Name, ...) \ case TypeKind::Name##Storage: @@ -1701,6 +1702,13 @@ CanType TypeBase::computeCanonicalType() { break; } + case TypeKind::PackElement: { + auto *element = cast(this); + auto packType = element->getPackType()->getCanonicalType(); + Result = PackElementType::get(packType, element->getLevel()); + break; + } + case TypeKind::Tuple: { TupleType *TT = cast(this); assert(TT->getNumElements() != 0 && "Empty tuples are always canonical"); @@ -5846,6 +5854,20 @@ case TypeKind::Id: return PackExpansionType::get(transformedPat, transformedCount); } + case TypeKind::PackElement: { + auto element = cast(base); + + Type transformedPack = + element->getPackType().transformWithPosition(pos, fn); + if (!transformedPack) + return Type(); + + if (transformedPack.getPointer() == element->getPackType().getPointer()) + return *this; + + return PackElementType::get(transformedPack, element->getLevel()); + } + case TypeKind::Tuple: { auto tuple = cast(base); bool anyChanged = false; @@ -6383,6 +6405,7 @@ ReferenceCounting TypeBase::getReferenceCounting() { case TypeKind::DependentMember: case TypeKind::Pack: case TypeKind::PackExpansion: + case TypeKind::PackElement: case TypeKind::SILPack: case TypeKind::BuiltinTuple: #define REF_STORAGE(Name, ...) \ diff --git a/lib/AST/TypeWalker.cpp b/lib/AST/TypeWalker.cpp index e9bef0a22f6..f38dd084775 100644 --- a/lib/AST/TypeWalker.cpp +++ b/lib/AST/TypeWalker.cpp @@ -70,6 +70,10 @@ class Traversal : public TypeVisitor return doIt(ty->getPatternType()); } + bool visitPackElementType(PackElementType *ty) { + return doIt(ty->getPackType()); + } + bool visitParenType(ParenType *ty) { return doIt(ty->getUnderlyingType()); } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 58d31100898..4b99148be5b 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -1960,6 +1960,7 @@ private: NEVER_VISIT(PackType) NEVER_VISIT(PackExpansionType) + NEVER_VISIT(PackElementType) NEVER_VISIT(TypeVariableType) VISIT(SugarType, recurse) diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 959b15cb9cf..b73e9031056 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -340,6 +340,7 @@ private: return Node->getChild(0)->getChild(0)->getNumChildren() == 0; case Node::Kind::ConstrainedExistential: + case Node::Kind::PackElement: case Node::Kind::PackExpansion: case Node::Kind::ProtocolListWithClass: case Node::Kind::AccessorAttachedMacroExpansion: @@ -1628,6 +1629,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, print(Node->getChild(0), depth + 1); return nullptr; } + case Node::Kind::PackElement: { + Printer << "each "; + print(Node->getChild(0), depth + 1); + return nullptr; + } case Node::Kind::ReturnType: if (Node->getNumChildren() == 0) Printer << " -> " << Node->getText(); diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 9bceeadb4d4..d6bc0900d37 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -1930,6 +1930,10 @@ ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } +ManglingError Remangler::manglePackElement(Node *node, unsigned depth) { + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} + ManglingError Remangler::mangleDependentGenericType(Node *node, unsigned depth) { Buffer << 'u'; diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index c2340bb6ec4..9eeff4511fc 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -2306,6 +2306,13 @@ ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError Remangler::manglePackElement(Node *node, unsigned depth) { + // FIXME + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); +// Buffer << "Qp"; + return ManglingError::Success; +} + ManglingError Remangler::mangleNumber(Node *node, unsigned depth) { mangleIndex(node->getIndex()); return ManglingError::Success; diff --git a/lib/IRGen/Fulfillment.cpp b/lib/IRGen/Fulfillment.cpp index b824fac61fe..6dd1247183c 100644 --- a/lib/IRGen/Fulfillment.cpp +++ b/lib/IRGen/Fulfillment.cpp @@ -54,6 +54,7 @@ static bool isLeafTypeMetadata(CanType type) { case TypeKind::InOut: case TypeKind::DynamicSelf: case TypeKind::PackExpansion: + case TypeKind::PackElement: case TypeKind::BuiltinTuple: llvm_unreachable("these types do not have metadata"); diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index f77468ae804..51563d0857c 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -2354,6 +2354,7 @@ const TypeInfo *TypeConverter::convertType(CanType ty) { return convertPackType(cast(ty)); case TypeKind::PackArchetype: case TypeKind::PackExpansion: + case TypeKind::PackElement: llvm_unreachable("pack archetypes and expansions should not be seen in " " arbitrary type positions"); case TypeKind::SILToken: diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 67201e4a733..d397286df54 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1551,6 +1551,7 @@ private: } case TypeKind::Pack: + case TypeKind::PackElement: llvm_unreachable("Unimplemented!"); case TypeKind::SILPack: diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 2764e854d7d..5eae25eb331 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -1504,6 +1504,11 @@ namespace { llvm_unreachable("cannot emit metadata for a pack expansion by itself"); } + MetadataResponse visitPackElementType(CanPackElementType type, + DynamicMetadataRequest request) { + llvm_unreachable("cannot emit metadata for a pack element by itself"); + } + MetadataResponse visitTupleType(CanTupleType type, DynamicMetadataRequest request) { if (auto cached = tryGetLocal(type, request)) @@ -2833,6 +2838,10 @@ static bool shouldAccessByMangledName(IRGenModule &IGM, CanType type) { llvm_unreachable("Unimplemented!"); } + void visitPackElementType(CanPackElementType tup) { + llvm_unreachable("Unimplemented!"); + } + void visitTupleType(CanTupleType tup) { // The empty tuple has trivial metadata. if (tup->getNumElements() == 0) { @@ -3274,6 +3283,10 @@ public: return ty; } + CanType visitPackElementType(CanPackElementType ty) { + llvm_unreachable("not implemented for PackElementType"); + } + CanType visitTupleType(CanTupleType ty) { bool changed = false; SmallVector loweredElts; @@ -3604,6 +3617,11 @@ namespace { llvm_unreachable(""); } + llvm::Value *visitPackElementType(CanPackElementType type, + DynamicMetadataRequest request) { + llvm_unreachable("not implemented for PackElementType"); + } + llvm::Value *visitTupleType(CanTupleType type, DynamicMetadataRequest request) { // Tuples containing pack expansion types are completely dynamic. diff --git a/lib/PrintAsClang/DeclAndTypePrinter.cpp b/lib/PrintAsClang/DeclAndTypePrinter.cpp index ca28788a639..ffe9053adb9 100644 --- a/lib/PrintAsClang/DeclAndTypePrinter.cpp +++ b/lib/PrintAsClang/DeclAndTypePrinter.cpp @@ -2684,6 +2684,10 @@ private: os << "void"; } + void visitPackElementType(PackElementType *PET, Optional optionalKind) { + llvm_unreachable("Not implemented"); + } + void visitParenType(ParenType *PT, Optional optionalKind) { visitPart(PT->getSinglyDesugaredType(), optionalKind); } diff --git a/lib/SIL/IR/AbstractionPattern.cpp b/lib/SIL/IR/AbstractionPattern.cpp index f547218c118..4d30c43856d 100644 --- a/lib/SIL/IR/AbstractionPattern.cpp +++ b/lib/SIL/IR/AbstractionPattern.cpp @@ -2168,6 +2168,11 @@ public: llvm_unreachable("shouldn't encounter pack expansion by itself"); } + CanType visitPackElementType(CanPackElementType packElement, + AbstractionPattern pattern) { + llvm_unreachable("shouldn't encounter pack element by itself"); + } + CanType handlePackExpansion(AbstractionPattern origExpansion, CanType candidateSubstType) { // When we're within a pack expansion, pack references matching that diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index 774e93330eb..5ef859c2c9c 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -351,6 +351,12 @@ namespace { return asImpl().handleAddressOnly(type, props); } + RetTy visitPackElementType(CanPackElementType type, + AbstractionPattern origType, + IsTypeExpansionSensitive_t isSensitive) { + llvm_unreachable("not implemented for PackElementType"); + } + RetTy visitBuiltinRawPointerType(CanBuiltinRawPointerType type, AbstractionPattern orig, IsTypeExpansionSensitive_t isSensitive) { @@ -2252,6 +2258,12 @@ namespace { return handleAddressOnly(packExpansionType, properties); } + TypeLowering *visitPackElementType(CanPackElementType packElementType, + AbstractionPattern origType, + IsTypeExpansionSensitive_t isSensitive) { + llvm_unreachable("not implemented for PackElementType"); + } + TypeLowering *visitBuiltinTupleType(CanBuiltinTupleType type, AbstractionPattern origType, IsTypeExpansionSensitive_t isSensitive) { @@ -3058,6 +3070,10 @@ TypeConverter::computeLoweredRValueType(TypeExpansionContext forExpansion, loweredSubstCountType)); } + CanType visitPackElementType(CanPackElementType substPackElementType) { + llvm_unreachable("not implemented for PackElementType"); + } + CanType visitBuiltinTupleType(CanBuiltinTupleType type) { llvm_unreachable("BuiltinTupleType should not show up here"); } diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index c255fbd4788..b209fbb24c1 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -7219,7 +7219,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, /*isImplicit*/ true)); } - case TypeKind::Pack: { + case TypeKind::Pack: + case TypeKind::PackElement: { llvm_unreachable("Unimplemented!"); } @@ -7600,6 +7601,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, case TypeKind::InOut: case TypeKind::Pack: case TypeKind::PackExpansion: + case TypeKind::PackElement: break; case TypeKind::BuiltinTuple: diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6301238919a..b051c64fd67 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -7308,6 +7308,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, return matchPackExpansionTypes(expansion1, expansion2, kind, subflags, locator); } + + case TypeKind::PackElement: { + auto pack1 = cast(desugar1)->getPackType(); + auto pack2 = cast(desugar2)->getPackType(); + + return matchTypes(pack1, pack2, kind, subflags, locator); + } } } @@ -7962,7 +7969,8 @@ ConstraintSystem::simplifyConstructionConstraint( case TypeKind::InOut: case TypeKind::Module: case TypeKind::Pack: - case TypeKind::PackExpansion: { + case TypeKind::PackExpansion: + case TypeKind::PackElement: { // If solver is in the diagnostic mode and this is an invalid base, // let's give solver a chance to repair it to produce a good diagnostic. if (shouldAttemptFixes()) diff --git a/lib/Serialization/DeclTypeRecordNodes.def b/lib/Serialization/DeclTypeRecordNodes.def index a29b8d88f7f..5b2cf387ba2 100644 --- a/lib/Serialization/DeclTypeRecordNodes.def +++ b/lib/Serialization/DeclTypeRecordNodes.def @@ -114,6 +114,7 @@ TYPE(SIL_BOX) TYPE(NAME_ALIAS) TYPE(PACK_EXPANSION) +TYPE(PACK_ELEMENT) TYPE(PACK) TYPE(SIL_PACK) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index f0eb0a37ade..0e4b8176603 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -7067,6 +7067,19 @@ Expected DESERIALIZE_TYPE(PACK_EXPANSION_TYPE)( return PackExpansionType::get(patternTy.get(), countTy.get()); } +Expected DESERIALIZE_TYPE(PACK_ELEMENT_TYPE)( + ModuleFile &MF, SmallVectorImpl &scratch, StringRef blobData) { + TypeID packID; + unsigned level; + decls_block::PackElementTypeLayout::readRecord(scratch, packID, level); + + auto packType = MF.getTypeChecked(packID); + if (!packType) + return packType.takeError(); + + return PackElementType::get(packType.get(), level); +} + Expected DESERIALIZE_TYPE(PACK_TYPE)( ModuleFile &MF, SmallVectorImpl &scratch, StringRef blobData) { ArrayRef elementTypeIDs; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 917215c2b98..9c0731b1b53 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 782; // reborrow, escaped SIL flags +const uint16_t SWIFTMODULE_VERSION_MINOR = 783; // pack element type /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1365,6 +1365,12 @@ namespace decls_block { TypeIDField // count type ); + TYPE_LAYOUT(PackElementTypeLayout, + PACK_ELEMENT_TYPE, + TypeIDField, // pack type + BCFixed<32> // level + ); + TYPE_LAYOUT(PackTypeLayout, PACK_TYPE, BCArray // component types diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 201e6ed456f..0fef132a713 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -5068,6 +5068,14 @@ public: S.addTypeRef(expansionTy->getCountType())); } + void visitPackElementType(const PackElementType *elementType) { + using namespace decls_block; + unsigned abbrCode = S.DeclTypeAbbrCodes[PackElementTypeLayout::Code]; + PackElementTypeLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, + S.addTypeRef(elementType->getPackType()), + elementType->getLevel()); + } + void visitPackType(const PackType *packTy) { using namespace decls_block; unsigned abbrCode = S.DeclTypeAbbrCodes[PackTypeLayout::Code];