Skip to content

Commit 000017d

Browse files
committed
AST: Introduce PackElementType
1 parent e49fccf commit 000017d

29 files changed

+274
-4
lines changed

include/swift/AST/TypeDifferenceVisitor.h

Lines changed: 5 additions & 0 deletions
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

Lines changed: 12 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6994,13 +6994,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69946994
}
69956995
END_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69966996

6997-
69986997
inline CanTypeWrapper<PackExpansionType>
69996998
CanPackType::unwrapSingletonPackExpansion() const {
70006999
return CanPackExpansionType(
70017000
getPointer()->unwrapSingletonPackExpansion());
70027001
}
70037002

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

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ struct ASTContext::Implementation {
417417
llvm::FoldingSet<TupleType> TupleTypes;
418418
llvm::FoldingSet<PackType> PackTypes;
419419
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
420+
llvm::FoldingSet<PackElementType> PackElementTypes;
420421
llvm::DenseMap<llvm::PointerIntPair<TypeBase*, 3, unsigned>,
421422
MetatypeType*> MetatypeTypes;
422423
llvm::DenseMap<llvm::PointerIntPair<TypeBase*, 3, unsigned>,
@@ -3290,6 +3291,47 @@ PackType *PackType::getEmpty(const ASTContext &C) {
32903291
return cast<PackType>(CanType(C.TheEmptyPackType));
32913292
}
32923293

3294+
PackElementType::PackElementType(Type packType, unsigned level,
3295+
RecursiveTypeProperties properties,
3296+
const ASTContext *canCtx)
3297+
: TypeBase(TypeKind::PackElement, canCtx, properties),
3298+
packType(packType), level(level) {
3299+
assert(packType->isParameterPack() ||
3300+
packType->is<PackArchetypeType>() ||
3301+
packType->is<TypeVariableType>());
3302+
assert(level > 0);
3303+
}
3304+
3305+
PackElementType *PackElementType::get(Type packType, unsigned level) {
3306+
auto properties = packType->getRecursiveProperties();
3307+
auto arena = getArena(properties);
3308+
3309+
auto &context = packType->getASTContext();
3310+
llvm::FoldingSetNodeID id;
3311+
PackElementType::Profile(id, packType, level);
3312+
3313+
void *insertPos;
3314+
if (PackElementType *elementType =
3315+
context.getImpl().getArena(arena)
3316+
.PackElementTypes.FindNodeOrInsertPos(id, insertPos))
3317+
return elementType;
3318+
3319+
const ASTContext *canCtx = packType->isCanonical()
3320+
? &context : nullptr;
3321+
PackElementType *elementType =
3322+
new (context, arena) PackElementType(packType, level, properties,
3323+
canCtx);
3324+
context.getImpl().getArena(arena).PackElementTypes.InsertNode(elementType,
3325+
insertPos);
3326+
return elementType;
3327+
}
3328+
3329+
void PackElementType::Profile(llvm::FoldingSetNodeID &ID,
3330+
Type packType, unsigned level) {
3331+
ID.AddPointer(packType.getPointer());
3332+
ID.AddInteger(level);
3333+
}
3334+
32933335
CanPackType CanPackType::get(const ASTContext &C, ArrayRef<CanType> elements) {
32943336
SmallVector<Type, 8> ncElements(elements.begin(), elements.end());
32953337
return CanPackType(PackType::get(C, ncElements));

lib/AST/ASTDumper.cpp

Lines changed: 7 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6049,6 +6049,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60496049
visit(T->getPatternType());
60506050
}
60516051

6052+
void visitPackElementType(PackElementType *T) {
6053+
Printer << "@level(" << T->getLevel() << ") ";
6054+
visit(T->getPackType());
6055+
}
6056+
60526057
void visitTupleType(TupleType *T) {
60536058
Printer.callPrintStructurePre(PrintStructureKind::TupleType);
60546059
SWIFT_DEFER { Printer.printStructurePost(PrintStructureKind::TupleType); };

lib/AST/ExistentialGeneralization.cpp

Lines changed: 1 addition & 0 deletions
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.

0 commit comments

Comments
 (0)