@@ -710,8 +710,10 @@ class alignas(1 << TypeAlignInBits) TypeBase
710710 SmallVectorImpl<OpenedArchetypeType *> &rootOpenedArchetypes) const ;
711711
712712 // / Retrieve the set of type parameter packs that occur within this type.
713- void getTypeParameterPacks (
714- SmallVectorImpl<Type> &rootParameterPacks);
713+ void getTypeParameterPacks (SmallVectorImpl<Type> &rootParameterPacks);
714+
715+ // / Retrieve the set of type parameter packs that occur within this type.
716+ void walkPackReferences (llvm::function_ref<bool (Type)> fn);
715717
716718 // / Replace opened archetypes with the given root with their most
717719 // / specific non-dependent upper bounds throughout this type.
@@ -778,6 +780,9 @@ class alignas(1 << TypeAlignInBits) TypeBase
778780 // / this function will wrap into a pack containing a singleton expansion.
779781 PackType *getPackSubstitutionAsPackType ();
780782
783+ // / Increase the expansion level of each parameter pack appearing in this type.
784+ Type increasePackElementLevel (unsigned level);
785+
781786 // / Determines whether this type is an lvalue. This includes both straight
782787 // / lvalue types as well as tuples or optionals of lvalues.
783788 bool hasLValueType () {
@@ -6412,7 +6417,7 @@ class PackArchetypeType final
64126417 LayoutConstraint Layout);
64136418
64146419 // Returns the reduced shape type for this pack archetype.
6415- CanType getReducedShape () const ;
6420+ CanType getReducedShape ();
64166421
64176422 static bool classof (const TypeBase *T) {
64186423 return T->getKind () == TypeKind::PackArchetype;
@@ -6994,13 +6999,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69946999 }
69957000END_CAN_TYPE_WRAPPER (PackExpansionType, Type)
69967001
6997-
69987002inline CanTypeWrapper<PackExpansionType>
69997003CanPackType::unwrapSingletonPackExpansion () const {
70007004 return CanPackExpansionType (
70017005 getPointer ()->unwrapSingletonPackExpansion ());
70027006}
70037007
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+
70047067// / getASTContext - Return the ASTContext that this type belongs to.
70057068inline ASTContext &TypeBase::getASTContext () const {
70067069 // If this type is canonical, it has the ASTContext in it.
@@ -7035,16 +7098,6 @@ inline bool TypeBase::isTypeParameter() {
70357098 return t->is <GenericTypeParamType>();
70367099}
70377100
7038- inline bool TypeBase::isParameterPack () {
7039- Type t (this );
7040-
7041- while (auto *memberTy = t->getAs <DependentMemberType>())
7042- t = memberTy->getBase ();
7043-
7044- return t->is <GenericTypeParamType>() &&
7045- t->castTo <GenericTypeParamType>()->isParameterPack ();
7046- }
7047-
70487101// TODO: This will become redundant once InOutType is removed.
70497102inline bool TypeBase::isMaterializable () {
70507103 return !(hasLValueType () || is<InOutType>());
0 commit comments