Skip to content

Commit ecc1d25

Browse files
authored
Merge pull request #64976 from slavapestov/more-variadic-generics-cherry-picks-5.9
[5.9] More variadic generics cherry picks
2 parents aac83a9 + 6449d48 commit ecc1d25

File tree

15 files changed

+384
-183
lines changed

15 files changed

+384
-183
lines changed

include/swift/AST/Types.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ class TypeAliasType final
20812081
/// this type references.
20822082
ArrayRef<Type> getDirectGenericArgs() const;
20832083

2084-
PackType *getExpandedGenericArgsPack();
2084+
SmallVector<Type, 2> getExpandedGenericArgs();
20852085

20862086
// Support for FoldingSet.
20872087
void Profile(llvm::FoldingSetNodeID &id) const;
@@ -2562,7 +2562,7 @@ class BoundGenericType : public NominalOrBoundGenericNominalType,
25622562
return {getTrailingObjectsPointer(), Bits.BoundGenericType.GenericArgCount};
25632563
}
25642564

2565-
PackType *getExpandedGenericArgsPack();
2565+
SmallVector<Type, 2> getExpandedGenericArgs();
25662566

25672567
void Profile(llvm::FoldingSetNodeID &ID) {
25682568
Profile(ID, getDecl(), getParent(), getGenericArgs());
@@ -6820,15 +6820,15 @@ class PackType final : public TypeBase, public llvm::FoldingSetNode,
68206820
/// Creates a pack from the types in \p elements.
68216821
static PackType *get(const ASTContext &C, ArrayRef<Type> elements);
68226822

6823-
static PackType *get(const ASTContext &C,
6824-
TypeArrayView<GenericTypeParamType> params,
6825-
ArrayRef<Type> args);
6826-
68276823
/// Given a type T, which must be a pack parameter, a member type
68286824
/// of a pack parameter, or a pack archetype, construct the type
68296825
/// Pack{repeat each T}.
68306826
static PackType *getSingletonPackExpansion(Type packParameter);
68316827

6828+
static SmallVector<Type, 2> getExpandedGenericArgs(
6829+
TypeArrayView<GenericTypeParamType> params,
6830+
ArrayRef<Type> args);
6831+
68326832
public:
68336833
/// Retrieves the number of elements in this pack.
68346834
unsigned getNumElements() const { return Bits.PackType.Count; }

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(
100100
hasSwiftSwiftParser)
101101
LANGUAGE_FEATURE(AttachedMacros, 389, "Attached macros", hasSwiftSwiftParser)
102102
LANGUAGE_FEATURE(MoveOnly, 390, "noncopyable types", true)
103+
LANGUAGE_FEATURE(ParameterPacks, 393, "Value and type parameter packs", true)
103104

104105
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
105106
UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)

lib/AST/ASTPrinter.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3328,15 +3328,15 @@ static bool usesFeatureFreestandingExpressionMacros(Decl *decl) {
33283328
static void
33293329
suppressingFeatureFreestandingExpressionMacros(PrintOptions &options,
33303330
llvm::function_ref<void()> action) {
3331-
llvm::SaveAndRestore<PrintOptions> orignalOptions(options);
3331+
llvm::SaveAndRestore<PrintOptions> originalOptions(options);
33323332
options.SuppressingFreestandingExpression = true;
33333333
action();
33343334
}
33353335

33363336
static void
33373337
suppressingFeatureNoAsyncAvailability(PrintOptions &options,
33383338
llvm::function_ref<void()> action) {
3339-
llvm::SaveAndRestore<PrintOptions> orignalOptions(options);
3339+
llvm::SaveAndRestore<PrintOptions> originalOptions(options);
33403340
options.SuppressNoAsyncAvailabilityAttr = true;
33413341
action();
33423342
}
@@ -3346,6 +3346,43 @@ static bool usesFeatureReferenceBindings(Decl *decl) {
33463346
return vd && vd->getIntroducer() == VarDecl::Introducer::InOut;
33473347
}
33483348

3349+
static bool hasParameterPacks(Decl *decl) {
3350+
if (auto genericContext = decl->getAsGenericContext()) {
3351+
auto sig = genericContext->getGenericSignature();
3352+
if (llvm::any_of(
3353+
sig.getGenericParams(),
3354+
[&](const GenericTypeParamType *GP) { return GP->isParameterPack(); })) {
3355+
return true;
3356+
}
3357+
}
3358+
3359+
return false;
3360+
}
3361+
3362+
/// A declaration needs the $ParameterPacks feature if it declares a
3363+
/// generic parameter pack, or if its type references a generic nominal
3364+
/// or type alias which declares a generic parameter pack.
3365+
static bool usesFeatureParameterPacks(Decl *decl) {
3366+
if (hasParameterPacks(decl))
3367+
return true;
3368+
3369+
if (auto *valueDecl = dyn_cast<ValueDecl>(decl)) {
3370+
if (valueDecl->getInterfaceType().findIf(
3371+
[&](Type t) {
3372+
if (auto *alias = dyn_cast<TypeAliasType>(t.getPointer()))
3373+
return hasParameterPacks(alias->getDecl());
3374+
if (auto *nominal = t->getAnyNominal())
3375+
return hasParameterPacks(nominal);
3376+
3377+
return false;
3378+
})) {
3379+
return true;
3380+
}
3381+
}
3382+
3383+
return false;
3384+
}
3385+
33493386
/// Suppress the printing of a particular feature.
33503387
static void suppressingFeature(PrintOptions &options, Feature feature,
33513388
llvm::function_ref<void()> action) {
@@ -5596,9 +5633,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
55965633
Optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
55975634
VisibleClangModules;
55985635

5599-
void printGenericArgs(PackType *flatArgs) {
5636+
void printGenericArgs(ArrayRef<Type> flatArgs) {
56005637
Printer << "<";
5601-
interleave(flatArgs->getElementTypes(),
5638+
interleave(flatArgs,
56025639
[&](Type arg) { visit(arg); },
56035640
[&] { Printer << ", "; });
56045641
Printer << ">";
@@ -5607,7 +5644,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
56075644
void printGenericArgs(ASTContext &ctx,
56085645
TypeArrayView<GenericTypeParamType> params,
56095646
ArrayRef<Type> args) {
5610-
printGenericArgs(PackType::get(ctx, params, args));
5647+
printGenericArgs(PackType::getExpandedGenericArgs(params, args));
56115648
}
56125649

56135650
/// Helper function for printing a type that is embedded within a larger type.
@@ -5958,7 +5995,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
59585995

59595996
auto *typeAliasDecl = T->getDecl();
59605997
if (typeAliasDecl->isGeneric()) {
5961-
printGenericArgs(T->getExpandedGenericArgsPack());
5998+
printGenericArgs(T->getExpandedGenericArgs());
59625999
}
59636000
}
59646001

@@ -6063,7 +6100,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60636100
}
60646101
printQualifiedType(T);
60656102

6066-
printGenericArgs(T->getExpandedGenericArgsPack());
6103+
printGenericArgs(T->getExpandedGenericArgs());
60676104
}
60686105

60696106
void visitParentType(Type T) {

lib/AST/ParameterPack.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ struct PackTypeParameterCollector: TypeWalker {
4040
if (auto parentType = boundGenericType->getParent())
4141
parentType.walk(*this);
4242

43-
Type(boundGenericType->getExpandedGenericArgsPack()).walk(*this);
43+
for (auto type : boundGenericType->getExpandedGenericArgs())
44+
type.walk(*this);
45+
4446
return Action::SkipChildren;
4547
}
4648

@@ -49,7 +51,9 @@ struct PackTypeParameterCollector: TypeWalker {
4951
if (auto parentType = typeAliasType->getParent())
5052
parentType.walk(*this);
5153

52-
Type(typeAliasType->getExpandedGenericArgsPack()).walk(*this);
54+
for (auto type : typeAliasType->getExpandedGenericArgs())
55+
type.walk(*this);
56+
5357
return Action::SkipChildren;
5458
}
5559
}
@@ -244,7 +248,7 @@ unsigned ParameterList::getOrigParamIndex(SubstitutionMap subMap,
244248
}
245249

246250
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
247-
PackType *BoundGenericType::getExpandedGenericArgsPack() {
251+
SmallVector<Type, 2> BoundGenericType::getExpandedGenericArgs() {
248252
// It would be nicer to use genericSig.getInnermostGenericParams() here,
249253
// but that triggers a request cycle if we're in the middle of computing
250254
// the generic signature already.
@@ -253,26 +257,26 @@ PackType *BoundGenericType::getExpandedGenericArgsPack() {
253257
params.push_back(paramDecl->getDeclaredInterfaceType());
254258
}
255259

256-
return PackType::get(getASTContext(),
260+
return PackType::getExpandedGenericArgs(
257261
TypeArrayView<GenericTypeParamType>(params),
258262
getGenericArgs());
259263
}
260264

261265
/// <T...> Foo<T, Pack{Int, String}> => Pack{T..., Int, String}
262-
PackType *TypeAliasType::getExpandedGenericArgsPack() {
266+
SmallVector<Type, 2> TypeAliasType::getExpandedGenericArgs() {
263267
if (!getDecl()->isGeneric())
264-
return nullptr;
268+
return SmallVector<Type, 2>();
265269

266270
auto genericSig = getGenericSignature();
267-
return PackType::get(getASTContext(),
271+
return PackType::getExpandedGenericArgs(
268272
genericSig.getInnermostGenericParams(),
269273
getDirectGenericArgs());
270274
}
271275

272-
/// <T...> Pack{T, Pack{Int, String}} => Pack{T..., Int, String}
273-
PackType *PackType::get(const ASTContext &C,
274-
TypeArrayView<GenericTypeParamType> params,
275-
ArrayRef<Type> args) {
276+
/// <T...> Pack{T, Pack{Int, String}} => {T..., Int, String}
277+
SmallVector<Type, 2>
278+
PackType::getExpandedGenericArgs(TypeArrayView<GenericTypeParamType> params,
279+
ArrayRef<Type> args) {
276280
SmallVector<Type, 2> wrappedArgs;
277281

278282
assert(params.size() == args.size());
@@ -288,7 +292,7 @@ PackType *PackType::get(const ASTContext &C,
288292
wrappedArgs.push_back(arg);
289293
}
290294

291-
return get(C, wrappedArgs);
295+
return wrappedArgs;
292296
}
293297

294298
PackType *PackType::getSingletonPackExpansion(Type param) {
@@ -347,7 +351,7 @@ static CanPackType getApproximateFormalPackType(const ASTContext &ctx,
347351
Collection loweredEltTypes) {
348352
// Build an array of formal element types, but be lazy about it:
349353
// use the original array unless we see an element type that doesn't
350-
// work as a legal format type.
354+
// work as a legal formal type.
351355
Optional<SmallVector<CanType, 4>> formalEltTypes;
352356
for (auto i : indices(loweredEltTypes)) {
353357
auto loweredEltType = loweredEltTypes[i];

lib/AST/RequirementEnvironment.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ RequirementEnvironment::RequirementEnvironment(
108108
// invalid code.
109109
if (genericParam->getDepth() != 1)
110110
return Type();
111-
auto substGenericParam = GenericTypeParamType::get(
111+
Type substGenericParam = GenericTypeParamType::get(
112112
genericParam->isParameterPack(), depth, genericParam->getIndex(), ctx);
113+
if (genericParam->isParameterPack()) {
114+
substGenericParam = PackType::getSingletonPackExpansion(
115+
substGenericParam);
116+
}
113117
return substGenericParam;
114118
},
115119
[selfType, substConcreteType, conformance, conformanceDC, &ctx](

0 commit comments

Comments
 (0)