Skip to content

Commit 5ee7125

Browse files
committed
AST: Fix TypeBase::getTypeParameterPacks() to not walk into nested PackExpansionTypes
1 parent 07aae0c commit 5ee7125

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
661661

662662
/// Retrieve the set of type parameter packs that occur within this type.
663663
void getTypeParameterPacks(
664-
SmallVectorImpl<Type> &rootParameterPacks) const;
664+
SmallVectorImpl<Type> &rootParameterPacks);
665665

666666
/// Replace opened archetypes with the given root with their most
667667
/// specific non-dependent upper bounds throughout this type.

lib/AST/ParameterPack.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,38 @@
2424

2525
using namespace swift;
2626

27-
void TypeBase::getTypeParameterPacks(
28-
SmallVectorImpl<Type> &rootParameterPacks) const {
29-
llvm::SmallDenseSet<CanType, 2> visited;
27+
namespace {
28+
29+
/// Collects all unique pack type parameters referenced from the pattern type,
30+
/// skipping those captured by nested pack expansion types.
31+
struct PackTypeParameterCollector: TypeWalker {
32+
llvm::SetVector<Type> typeParams;
3033

31-
auto recordType = [&](Type t) {
32-
if (visited.insert(t->getCanonicalType()).second)
33-
rootParameterPacks.push_back(t);
34-
};
34+
Action walkToTypePre(Type t) override {
35+
if (t->is<PackExpansionType>())
36+
return Action::SkipChildren;
3537

36-
Type(const_cast<TypeBase *>(this)).visit([&](Type t) {
3738
if (auto *paramTy = t->getAs<GenericTypeParamType>()) {
38-
if (paramTy->isParameterPack()) {
39-
recordType(paramTy);
40-
}
39+
if (paramTy->isParameterPack())
40+
typeParams.insert(paramTy);
4141
} else if (auto *archetypeTy = t->getAs<PackArchetypeType>()) {
42-
if (archetypeTy->isRoot()) {
43-
recordType(t);
44-
}
42+
if (archetypeTy->isRoot())
43+
typeParams.insert(paramTy);
4544
}
46-
});
45+
46+
return Action::Continue;
47+
}
48+
};
49+
50+
}
51+
52+
void TypeBase::getTypeParameterPacks(
53+
SmallVectorImpl<Type> &rootParameterPacks) {
54+
PackTypeParameterCollector collector;
55+
Type(this).walk(collector);
56+
57+
rootParameterPacks.append(collector.typeParams.begin(),
58+
collector.typeParams.end());
4759
}
4860

4961
bool GenericTypeParamType::isParameterPack() const {

0 commit comments

Comments
 (0)