Skip to content

Commit 9b3faad

Browse files
authored
Merge pull request #66126 from slavapestov/pack-element-refactoring
Preliminary work for introducing PackElementType
2 parents 44e1995 + 9d5b6d8 commit 9b3faad

32 files changed

+1478
-1174
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
@@ -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

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
@@ -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

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
@@ -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/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ add_swift_host_library(swiftAST STATIC
117117
TypeJoinMeet.cpp
118118
TypeRefinementContext.cpp
119119
TypeRepr.cpp
120+
TypeSubstitution.cpp
120121
TypeWalker.cpp
121122
UnqualifiedLookup.cpp
122123
USRGeneration.cpp

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)