Skip to content

Commit b2bc2c7

Browse files
committed
AST: Introduce PackElementType
1 parent 8f9a4cb commit b2bc2c7

29 files changed

+274
-4
lines changed

include/swift/AST/TypeDifferenceVisitor.h

+5
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor<Impl, bool> {
149149
return asImpl().visit(type1.getPatternType(), type2.getPatternType());
150150
}
151151

152+
bool visitPackElementType(CanPackElementType type1,
153+
CanPackElementType type2) {
154+
return asImpl().visit(type1.getPackType(), type2.getPackType());
155+
}
156+
152157
bool visitTupleType(CanTupleType type1, CanTupleType type2) {
153158
return visitComponentArray(type1, type2,
154159
type1->getElements(), type2->getElements());

include/swift/AST/TypeMatcher.h

+12
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ class TypeMatcher {
202202
return mismatch(firstPE.getPointer(), secondType, sugaredFirstType);
203203
}
204204

205+
bool visitPackElementType(CanPackElementType firstElement, Type secondType,
206+
Type sugaredFirstType) {
207+
if (auto secondElement = secondType->getAs<PackElementType>()) {
208+
return this->visit(firstElement.getPackType(),
209+
secondElement->getPackType(),
210+
sugaredFirstType->castTo<PackElementType>()
211+
->getPackType());
212+
}
213+
214+
return mismatch(firstElement.getPointer(), secondType, sugaredFirstType);
215+
}
216+
205217
bool visitReferenceStorageType(CanReferenceStorageType firstStorage,
206218
Type secondType, Type sugaredFirstType) {
207219
if (firstStorage->getKind() == secondType->getDesugaredType()->getKind()) {

include/swift/AST/TypeNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ TYPE(LValue, Type)
186186
TYPE(InOut, Type)
187187
TYPE(Pack, Type)
188188
TYPE(PackExpansion, Type)
189+
TYPE(PackElement, Type)
189190
UNCHECKED_TYPE(TypeVariable, Type)
190191
ABSTRACT_SUGARED_TYPE(Sugar, Type)
191192
SUGARED_TYPE(Paren, SugarType)

include/swift/AST/Types.h

+59-1
Original file line numberDiff line numberDiff line change
@@ -6999,13 +6999,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69996999
}
70007000
END_CAN_TYPE_WRAPPER(PackExpansionType, Type)
70017001

7002-
70037002
inline CanTypeWrapper<PackExpansionType>
70047003
CanPackType::unwrapSingletonPackExpansion() const {
70057004
return CanPackExpansionType(
70067005
getPointer()->unwrapSingletonPackExpansion());
70077006
}
70087007

7008+
/// Represents a reference to a pack from an outer expansion. This comes up
7009+
/// after substitution. For example, given these declarations:
7010+
///
7011+
/// typealias A<each T, U> = (repeat (each T, U))
7012+
/// typealias B<each X, repeat each Y> = (repeat A<repeat each X, each Y>)
7013+
///
7014+
/// Naively substituting replacing {T := repeat each X, U := each Y} in the
7015+
/// underlying type of A would give us:
7016+
///
7017+
/// '(repeat (repeat (each X, each Y)))'
7018+
///
7019+
/// However, this is wrong; we're not expanding X and Y in parallel (they
7020+
/// might not even have the same shape). Instead, we're expanding X, and
7021+
/// then on each iteration, expanding Y.
7022+
///
7023+
/// If we annotate each 'repeat' and its corresponding 'each', we instead see
7024+
/// that the above should give us:
7025+
///
7026+
/// '(repeat[1] (repeat[0] (each[0], each[1] U)))'
7027+
///
7028+
/// We number PackExpansionTypes from the innermost one outwards, assigning
7029+
/// a level of 0 to the innermost one. Then, a PackElementType represents a
7030+
/// reference to a parameter pack from an expansion with level > 0.
7031+
class PackElementType : public TypeBase, public llvm::FoldingSetNode {
7032+
friend class ASTContext;
7033+
7034+
Type packType;
7035+
unsigned level;
7036+
7037+
PackElementType(Type packType, unsigned level,
7038+
RecursiveTypeProperties properties,
7039+
const ASTContext *ctx);
7040+
7041+
public:
7042+
static PackElementType *get(Type packType, unsigned level);
7043+
7044+
Type getPackType() const { return packType; }
7045+
7046+
unsigned getLevel() const { return level; }
7047+
7048+
void Profile(llvm::FoldingSetNodeID &ID) {
7049+
Profile(ID, getPackType(), getLevel());
7050+
}
7051+
7052+
static void Profile(llvm::FoldingSetNodeID &ID, Type packType, unsigned level);
7053+
7054+
// Implement isa/cast/dyncast/etc.
7055+
static bool classof(const TypeBase *T) {
7056+
return T->getKind() == TypeKind::PackElement;
7057+
}
7058+
};
7059+
BEGIN_CAN_TYPE_WRAPPER(PackElementType, Type)
7060+
static CanPackElementType get(CanType pack);
7061+
7062+
CanType getPackType() const {
7063+
return CanType(getPointer()->getPackType());
7064+
}
7065+
END_CAN_TYPE_WRAPPER(PackElementType, Type)
7066+
70097067
/// getASTContext - Return the ASTContext that this type belongs to.
70107068
inline ASTContext &TypeBase::getASTContext() const {
70117069
// If this type is canonical, it has the ASTContext in it.

include/swift/Demangling/DemangleNodes.def

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ NODE(Pack)
241241
NODE(SILPackDirect)
242242
NODE(SILPackIndirect)
243243
NODE(PackExpansion)
244+
NODE(PackElement)
244245
NODE(Type)
245246
CONTEXT_NODE(TypeSymbolicReference)
246247
CONTEXT_NODE(TypeAlias)

lib/AST/ASTContext.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ struct ASTContext::Implementation {
416416
llvm::FoldingSet<TupleType> TupleTypes;
417417
llvm::FoldingSet<PackType> PackTypes;
418418
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
419+
llvm::FoldingSet<PackElementType> PackElementTypes;
419420
llvm::DenseMap<llvm::PointerIntPair<TypeBase*, 3, unsigned>,
420421
MetatypeType*> MetatypeTypes;
421422
llvm::DenseMap<llvm::PointerIntPair<TypeBase*, 3, unsigned>,
@@ -3317,6 +3318,47 @@ PackType *PackType::getEmpty(const ASTContext &C) {
33173318
return cast<PackType>(CanType(C.TheEmptyPackType));
33183319
}
33193320

3321+
PackElementType::PackElementType(Type packType, unsigned level,
3322+
RecursiveTypeProperties properties,
3323+
const ASTContext *canCtx)
3324+
: TypeBase(TypeKind::PackElement, canCtx, properties),
3325+
packType(packType), level(level) {
3326+
assert(packType->isParameterPack() ||
3327+
packType->is<PackArchetypeType>() ||
3328+
packType->is<TypeVariableType>());
3329+
assert(level > 0);
3330+
}
3331+
3332+
PackElementType *PackElementType::get(Type packType, unsigned level) {
3333+
auto properties = packType->getRecursiveProperties();
3334+
auto arena = getArena(properties);
3335+
3336+
auto &context = packType->getASTContext();
3337+
llvm::FoldingSetNodeID id;
3338+
PackElementType::Profile(id, packType, level);
3339+
3340+
void *insertPos;
3341+
if (PackElementType *elementType =
3342+
context.getImpl().getArena(arena)
3343+
.PackElementTypes.FindNodeOrInsertPos(id, insertPos))
3344+
return elementType;
3345+
3346+
const ASTContext *canCtx = packType->isCanonical()
3347+
? &context : nullptr;
3348+
PackElementType *elementType =
3349+
new (context, arena) PackElementType(packType, level, properties,
3350+
canCtx);
3351+
context.getImpl().getArena(arena).PackElementTypes.InsertNode(elementType,
3352+
insertPos);
3353+
return elementType;
3354+
}
3355+
3356+
void PackElementType::Profile(llvm::FoldingSetNodeID &ID,
3357+
Type packType, unsigned level) {
3358+
ID.AddPointer(packType.getPointer());
3359+
ID.AddInteger(level);
3360+
}
3361+
33203362
CanPackType CanPackType::get(const ASTContext &C, ArrayRef<CanType> elements) {
33213363
SmallVector<Type, 8> ncElements(elements.begin(), elements.end());
33223364
return CanPackType(PackType::get(C, ncElements));

lib/AST/ASTDumper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -3873,6 +3873,13 @@ namespace {
38733873
PrintWithColorRAII(OS, ParenthesisColor) << ')';
38743874
}
38753875

3876+
void visitPackElementType(PackElementType *T, StringRef label) {
3877+
printCommon(label, "element_type");
3878+
printField("level", T->getLevel());
3879+
printRec("pack", T->getPackType());
3880+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
3881+
}
3882+
38763883
void visitParenType(ParenType *T, StringRef label) {
38773884
printCommon(label, "paren_type");
38783885
printRec(T->getUnderlyingType());

lib/AST/ASTMangler.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,15 @@ void ASTMangler::appendType(Type type, GenericSignature sig,
12851285
return;
12861286
}
12871287

1288+
case TypeKind::PackElement: {
1289+
auto elementType = cast<PackElementType>(tybase);
1290+
appendType(elementType->getPackType(), sig, forDecl);
1291+
1292+
// FIXME: append expansion depth
1293+
1294+
return;
1295+
}
1296+
12881297
case TypeKind::Pack: {
12891298
auto packTy = cast<PackType>(tybase);
12901299

lib/AST/ASTPrinter.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -6073,6 +6073,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60736073
visit(T->getPatternType());
60746074
}
60756075

6076+
void visitPackElementType(PackElementType *T) {
6077+
Printer << "@level(" << T->getLevel() << ") ";
6078+
visit(T->getPackType());
6079+
}
6080+
60766081
void visitTupleType(TupleType *T) {
60776082
Printer.callPrintStructurePre(PrintStructureKind::TupleType);
60786083
SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); };

lib/AST/ExistentialGeneralization.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
158158
NO_PRESERVABLE_STRUCTURE(Module)
159159
NO_PRESERVABLE_STRUCTURE(Pack)
160160
NO_PRESERVABLE_STRUCTURE(PackExpansion)
161+
NO_PRESERVABLE_STRUCTURE(PackElement)
161162
#undef NO_PRESERVABLE_STRUCTURE
162163

163164
// These types simply shouldn't appear in types that we generalize at all.

lib/AST/Type.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
292292
case TypeKind::SILToken:
293293
case TypeKind::Pack:
294294
case TypeKind::PackExpansion:
295+
case TypeKind::PackElement:
295296
case TypeKind::SILPack:
296297
#define REF_STORAGE(Name, ...) \
297298
case TypeKind::Name##Storage:
@@ -1701,6 +1702,13 @@ CanType TypeBase::computeCanonicalType() {
17011702
break;
17021703
}
17031704

1705+
case TypeKind::PackElement: {
1706+
auto *element = cast<PackElementType>(this);
1707+
auto packType = element->getPackType()->getCanonicalType();
1708+
Result = PackElementType::get(packType, element->getLevel());
1709+
break;
1710+
}
1711+
17041712
case TypeKind::Tuple: {
17051713
TupleType *TT = cast<TupleType>(this);
17061714
assert(TT->getNumElements() != 0 && "Empty tuples are always canonical");
@@ -5846,6 +5854,20 @@ case TypeKind::Id:
58465854
return PackExpansionType::get(transformedPat, transformedCount);
58475855
}
58485856

5857+
case TypeKind::PackElement: {
5858+
auto element = cast<PackElementType>(base);
5859+
5860+
Type transformedPack =
5861+
element->getPackType().transformWithPosition(pos, fn);
5862+
if (!transformedPack)
5863+
return Type();
5864+
5865+
if (transformedPack.getPointer() == element->getPackType().getPointer())
5866+
return *this;
5867+
5868+
return PackElementType::get(transformedPack, element->getLevel());
5869+
}
5870+
58495871
case TypeKind::Tuple: {
58505872
auto tuple = cast<TupleType>(base);
58515873
bool anyChanged = false;
@@ -6383,6 +6405,7 @@ ReferenceCounting TypeBase::getReferenceCounting() {
63836405
case TypeKind::DependentMember:
63846406
case TypeKind::Pack:
63856407
case TypeKind::PackExpansion:
6408+
case TypeKind::PackElement:
63866409
case TypeKind::SILPack:
63876410
case TypeKind::BuiltinTuple:
63886411
#define REF_STORAGE(Name, ...) \

lib/AST/TypeWalker.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class Traversal : public TypeVisitor<Traversal, bool>
7070
return doIt(ty->getPatternType());
7171
}
7272

73+
bool visitPackElementType(PackElementType *ty) {
74+
return doIt(ty->getPackType());
75+
}
76+
7377
bool visitParenType(ParenType *ty) {
7478
return doIt(ty->getUnderlyingType());
7579
}

lib/ClangImporter/ImportType.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,7 @@ class GetSendableType :
19601960

19611961
NEVER_VISIT(PackType)
19621962
NEVER_VISIT(PackExpansionType)
1963+
NEVER_VISIT(PackElementType)
19631964
NEVER_VISIT(TypeVariableType)
19641965

19651966
VISIT(SugarType, recurse)

lib/Demangling/NodePrinter.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ class NodePrinter {
340340
return Node->getChild(0)->getChild(0)->getNumChildren() == 0;
341341

342342
case Node::Kind::ConstrainedExistential:
343+
case Node::Kind::PackElement:
343344
case Node::Kind::PackExpansion:
344345
case Node::Kind::ProtocolListWithClass:
345346
case Node::Kind::AccessorAttachedMacroExpansion:
@@ -1628,6 +1629,11 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
16281629
print(Node->getChild(0), depth + 1);
16291630
return nullptr;
16301631
}
1632+
case Node::Kind::PackElement: {
1633+
Printer << "each ";
1634+
print(Node->getChild(0), depth + 1);
1635+
return nullptr;
1636+
}
16311637
case Node::Kind::ReturnType:
16321638
if (Node->getNumChildren() == 0)
16331639
Printer << " -> " << Node->getText();

lib/Demangling/OldRemangler.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,10 @@ ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
19301930
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
19311931
}
19321932

1933+
ManglingError Remangler::manglePackElement(Node *node, unsigned depth) {
1934+
return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node);
1935+
}
1936+
19331937
ManglingError Remangler::mangleDependentGenericType(Node *node,
19341938
unsigned depth) {
19351939
Buffer << 'u';

lib/Demangling/Remangler.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -2306,6 +2306,13 @@ ManglingError Remangler::manglePackExpansion(Node *node, unsigned depth) {
23062306
return ManglingError::Success;
23072307
}
23082308

2309+
ManglingError Remangler::manglePackElement(Node *node, unsigned depth) {
2310+
// FIXME
2311+
RETURN_IF_ERROR(mangleChildNodes(node, depth + 1));
2312+
// Buffer << "Qp";
2313+
return ManglingError::Success;
2314+
}
2315+
23092316
ManglingError Remangler::mangleNumber(Node *node, unsigned depth) {
23102317
mangleIndex(node->getIndex());
23112318
return ManglingError::Success;

lib/IRGen/Fulfillment.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static bool isLeafTypeMetadata(CanType type) {
5454
case TypeKind::InOut:
5555
case TypeKind::DynamicSelf:
5656
case TypeKind::PackExpansion:
57+
case TypeKind::PackElement:
5758
case TypeKind::BuiltinTuple:
5859
llvm_unreachable("these types do not have metadata");
5960

lib/IRGen/GenType.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2354,6 +2354,7 @@ const TypeInfo *TypeConverter::convertType(CanType ty) {
23542354
return convertPackType(cast<SILPackType>(ty));
23552355
case TypeKind::PackArchetype:
23562356
case TypeKind::PackExpansion:
2357+
case TypeKind::PackElement:
23572358
llvm_unreachable("pack archetypes and expansions should not be seen in "
23582359
" arbitrary type positions");
23592360
case TypeKind::SILToken:

lib/IRGen/IRGenDebugInfo.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
15511551
}
15521552

15531553
case TypeKind::Pack:
1554+
case TypeKind::PackElement:
15541555
llvm_unreachable("Unimplemented!");
15551556

15561557
case TypeKind::SILPack:

0 commit comments

Comments
 (0)