Skip to content

Commit 3ac6c58

Browse files
committed
AST: Introduce {TypeAliasType,BoundGenericType}::getExpandedGenericArgsPack()
1 parent b122977 commit 3ac6c58

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

include/swift/AST/Types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Identifier;
7171
class InOutType;
7272
class OpaqueTypeDecl;
7373
class OpenedArchetypeType;
74+
class PackType;
7475
class PlaceholderTypeRepr;
7576
enum class ReferenceCounting : uint8_t;
7677
enum class ResilienceExpansion : unsigned;
@@ -2002,6 +2003,8 @@ class TypeAliasType final
20022003
/// this type references.
20032004
ArrayRef<Type> getDirectGenericArgs() const;
20042005

2006+
PackType *getExpandedGenericArgsPack();
2007+
20052008
// Support for FoldingSet.
20062009
void Profile(llvm::FoldingSetNodeID &id) const;
20072010

@@ -2420,6 +2423,8 @@ class BoundGenericType : public NominalOrBoundGenericNominalType,
24202423
return {getTrailingObjectsPointer(), Bits.BoundGenericType.GenericArgCount};
24212424
}
24222425

2426+
PackType *getExpandedGenericArgsPack();
2427+
24232428
void Profile(llvm::FoldingSetNodeID &ID) {
24242429
Profile(ID, getDecl(), getParent(), getGenericArgs());
24252430
}
@@ -6478,6 +6483,10 @@ class PackType final : public TypeBase, public llvm::FoldingSetNode,
64786483
/// Creates a pack from the types in \p elements.
64796484
static PackType *get(const ASTContext &C, ArrayRef<Type> elements);
64806485

6486+
static PackType *get(const ASTContext &C,
6487+
TypeArrayView<GenericTypeParamType> params,
6488+
ArrayRef<Type> args);
6489+
64816490
public:
64826491
/// Retrieves the number of elements in this pack.
64836492
unsigned getNumElements() const { return Bits.PackType.Count; }

lib/AST/ParameterPack.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/Decl.h"
20+
#include "swift/AST/GenericParamList.h"
2021
#include "swift/AST/ParameterList.h"
2122
#include "swift/AST/Type.h"
2223
#include "swift/AST/Types.h"
@@ -35,6 +36,24 @@ struct PackTypeParameterCollector: TypeWalker {
3536
if (t->is<PackExpansionType>())
3637
return Action::SkipChildren;
3738

39+
if (auto *boundGenericType = dyn_cast<BoundGenericType>(t.getPointer())) {
40+
if (auto parentType = boundGenericType->getParent())
41+
parentType.walk(*this);
42+
43+
Type(boundGenericType->getExpandedGenericArgsPack()).walk(*this);
44+
return Action::SkipChildren;
45+
}
46+
47+
if (auto *typeAliasType = dyn_cast<TypeAliasType>(t.getPointer())) {
48+
if (typeAliasType->getDecl()->isGeneric()) {
49+
if (auto parentType = typeAliasType->getParent())
50+
parentType.walk(*this);
51+
52+
Type(typeAliasType->getExpandedGenericArgsPack()).walk(*this);
53+
return Action::SkipChildren;
54+
}
55+
}
56+
3857
if (auto *paramTy = t->getAs<GenericTypeParamType>()) {
3958
if (paramTy->isParameterPack())
4059
typeParams.insert(paramTy);
@@ -348,3 +367,51 @@ unsigned ParameterList::getOrigParamIndex(SubstitutionMap subMap,
348367
dump(llvm::errs());
349368
abort();
350369
}
370+
371+
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
372+
PackType *BoundGenericType::getExpandedGenericArgsPack() {
373+
// It would be nicer to use genericSig.getInnermostGenericParams() here,
374+
// but that triggers a request cycle if we're in the middle of computing
375+
// the generic signature already.
376+
SmallVector<Type, 2> params;
377+
for (auto *paramDecl : getDecl()->getGenericParams()->getParams()) {
378+
params.push_back(paramDecl->getDeclaredInterfaceType());
379+
}
380+
381+
return PackType::get(getASTContext(),
382+
TypeArrayView<GenericTypeParamType>(params),
383+
getGenericArgs());
384+
}
385+
386+
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
387+
PackType *TypeAliasType::getExpandedGenericArgsPack() {
388+
if (!getDecl()->isGeneric())
389+
return nullptr;
390+
391+
auto genericSig = getGenericSignature();
392+
return PackType::get(getASTContext(),
393+
genericSig.getInnermostGenericParams(),
394+
getDirectGenericArgs());
395+
}
396+
397+
/// <T...> Pack{T, Pack{Int, String}} => Pack{T..., Int, String}
398+
PackType *PackType::get(const ASTContext &C,
399+
TypeArrayView<GenericTypeParamType> params,
400+
ArrayRef<Type> args) {
401+
SmallVector<Type, 2> wrappedArgs;
402+
403+
assert(params.size() == args.size());
404+
for (unsigned i = 0, e = params.size(); i < e; ++i) {
405+
auto arg = args[i];
406+
407+
if (params[i]->isParameterPack()) {
408+
wrappedArgs.push_back(PackExpansionType::get(
409+
arg, arg->getReducedShape()));
410+
continue;
411+
}
412+
413+
wrappedArgs.push_back(arg);
414+
}
415+
416+
return get(C, wrappedArgs)->flattenPackTypes();
417+
}

0 commit comments

Comments
 (0)