Skip to content

Commit 4611e15

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

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-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: 51 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"
@@ -348,3 +349,53 @@ unsigned ParameterList::getOrigParamIndex(SubstitutionMap subMap,
348349
dump(llvm::errs());
349350
abort();
350351
}
352+
353+
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
354+
PackType *BoundGenericType::getExpandedGenericArgsPack() {
355+
// It would be nicer to use genericSig.getInnermostGenericParams() here,
356+
// but that triggers a request cycle if we're in the middle of computing
357+
// the generic signature already.
358+
SmallVector<Type, 2> params;
359+
for (auto *paramDecl : getDecl()->getGenericParams()->getParams()) {
360+
params.push_back(paramDecl->getDeclaredInterfaceType());
361+
}
362+
363+
return PackType::get(getASTContext(),
364+
TypeArrayView<GenericTypeParamType>(params),
365+
getGenericArgs());
366+
}
367+
368+
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
369+
PackType *TypeAliasType::getExpandedGenericArgsPack() {
370+
auto genericSig = getGenericSignature();
371+
return PackType::get(getASTContext(),
372+
genericSig.getInnermostGenericParams(),
373+
getDirectGenericArgs());
374+
}
375+
376+
/// <T...> Pack{T, Pack{Int, String}} => Pack{T..., Int, String}
377+
PackType *PackType::get(const ASTContext &C,
378+
TypeArrayView<GenericTypeParamType> params,
379+
ArrayRef<Type> args) {
380+
SmallVector<Type, 2> wrappedArgs;
381+
382+
assert(params.size() == args.size());
383+
for (unsigned i = 0, e = params.size(); i < e; ++i) {
384+
auto arg = args[i];
385+
386+
if (params[i]->isParameterPack()) {
387+
assert(arg->is<PackType>() ||
388+
arg->is<PackArchetypeType>() ||
389+
arg->is<TypeVariableType>() ||
390+
arg->isParameterPack());
391+
392+
wrappedArgs.push_back(PackExpansionType::get(
393+
arg, arg->getReducedShape()));
394+
continue;
395+
}
396+
397+
wrappedArgs.push_back(arg);
398+
}
399+
400+
return get(C, wrappedArgs)->flattenPackTypes();
401+
}

0 commit comments

Comments
 (0)