@@ -29,12 +29,13 @@ namespace {
2929
3030// / Collects all unique pack type parameters referenced from the pattern type,
3131// / skipping those captured by nested pack expansion types.
32- struct PackTypeParameterCollector : TypeWalker {
33- llvm::SetVector< Type> typeParams ;
32+ struct PackReferenceCollector : TypeWalker {
33+ llvm::function_ref< bool ( Type)> fn ;
3434 unsigned expansionLevel;
3535 SmallVector<unsigned , 2 > elementLevel;
3636
37- PackTypeParameterCollector () : expansionLevel(0 ) {
37+ PackReferenceCollector (llvm::function_ref<bool (Type)> fn)
38+ : fn(fn), expansionLevel(0 ) {
3839 elementLevel.push_back (0 );
3940 }
4041
@@ -72,12 +73,8 @@ struct PackTypeParameterCollector: TypeWalker {
7273 }
7374
7475 if (elementLevel.back () == expansionLevel) {
75- if (auto *paramTy = t->getAs <GenericTypeParamType>()) {
76- if (paramTy->isParameterPack ())
77- typeParams.insert (paramTy);
78- } else if (auto *archetypeTy = t->getAs <PackArchetypeType>()) {
79- typeParams.insert (archetypeTy->getRoot ());
80- }
76+ if (fn (t))
77+ return Action::Stop;
8178 }
8279
8380 return Action::Continue;
@@ -96,13 +93,28 @@ struct PackTypeParameterCollector: TypeWalker {
9693
9794}
9895
96+ void TypeBase::walkPackReferences (
97+ llvm::function_ref<bool (Type)> fn) {
98+ Type (this ).walk (PackReferenceCollector (fn));
99+ }
100+
99101void TypeBase::getTypeParameterPacks (
100102 SmallVectorImpl<Type> &rootParameterPacks) {
101- PackTypeParameterCollector collector;
102- Type (this ).walk (collector);
103+ llvm::SmallSetVector<Type, 2 > rootParameterPackSet;
104+
105+ walkPackReferences ([&](Type t) {
106+ if (auto *paramTy = t->getAs <GenericTypeParamType>()) {
107+ if (paramTy->isParameterPack ())
108+ rootParameterPackSet.insert (paramTy);
109+ } else if (auto *archetypeTy = t->getAs <PackArchetypeType>()) {
110+ rootParameterPackSet.insert (archetypeTy->getRoot ());
111+ }
112+
113+ return false ;
114+ });
103115
104- rootParameterPacks.append (collector. typeParams .begin (),
105- collector. typeParams .end ());
116+ rootParameterPacks.append (rootParameterPackSet .begin (),
117+ rootParameterPackSet .end ());
106118}
107119
108120bool GenericTypeParamType::isParameterPack () const {
@@ -133,6 +145,45 @@ PackType *TypeBase::getPackSubstitutionAsPackType() {
133145 }
134146}
135147
148+ static Type increasePackElementLevelImpl (
149+ Type type, unsigned level, unsigned outerLevel) {
150+ assert (level > 0 );
151+
152+ return type.transformRec ([&](TypeBase *t) -> Optional<Type> {
153+ if (auto *elementType = dyn_cast<PackElementType>(t)) {
154+ if (elementType->getLevel () >= outerLevel) {
155+ elementType = PackElementType::get (elementType->getPackType (),
156+ elementType->getLevel () + level);
157+ }
158+
159+ return Type (elementType);
160+ }
161+
162+ if (auto *expansionType = dyn_cast<PackExpansionType>(t)) {
163+ return Type (PackExpansionType::get (
164+ increasePackElementLevelImpl (expansionType->getPatternType (),
165+ level, outerLevel + 1 ),
166+ expansionType->getCountType ()));
167+ }
168+
169+ if (t->isParameterPack () || isa<PackArchetypeType>(t)) {
170+ if (outerLevel == 0 )
171+ return Type (PackElementType::get (t, level));
172+
173+ return Type (t);
174+ }
175+
176+ return None;
177+ });
178+ }
179+
180+ Type TypeBase::increasePackElementLevel (unsigned level) {
181+ if (level == 0 )
182+ return Type (this );
183+
184+ return increasePackElementLevelImpl (Type (this ), level, 0 );
185+ }
186+
136187CanType PackExpansionType::getReducedShape () {
137188 auto reducedShape = countType->getReducedShape ();
138189 if (reducedShape == getASTContext ().TheEmptyTupleType )
0 commit comments