Skip to content

Commit f25e2d2

Browse files
committed
Sema: Diagnose variadic types with more than one type parameter pack
1 parent ea9bb20 commit f25e2d2

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5398,6 +5398,9 @@ ERROR(vararg_not_allowed,none,
53985398
ERROR(experimental_type_with_parameter_pack,none,
53995399
"generic types with parameter packs are experimental",
54005400
())
5401+
ERROR(more_than_one_parameter_pack_in_type,none,
5402+
"generic type cannot have more than one pack", ())
5403+
54015404
ERROR(expansion_not_allowed,none,
54025405
"pack expansion %0 can only appear in a function parameter list, "
54035406
"tuple element, or generic argument list", (Type))
@@ -5419,7 +5422,7 @@ ERROR(pack_reference_must_be_in_expansion,none,
54195422
"pack reference %0 requires expansion using keyword 'repeat'",
54205423
(TypeRepr*))
54215424
ERROR(pack_type_requires_keyword_each,none,
5422-
"pack type %0 must be referenced with 'each'",
5425+
"type pack %0 must be referenced with 'each'",
54235426
(TypeRepr*))
54245427
ERROR(tuple_duplicate_label,none,
54255428
"cannot create a tuple with a duplicate element label", ())

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,24 @@ static void checkGenericParams(GenericContext *ownerCtx) {
471471
if (!genericParams)
472472
return;
473473

474+
auto *decl = ownerCtx->getAsDecl();
475+
bool isGenericType = isa<GenericTypeDecl>(decl);
476+
bool hasPack = false;
477+
474478
for (auto gp : *genericParams) {
475479
// Diagnose generic types with a parameter packs if VariadicGenerics
476480
// is not enabled.
477-
auto *decl = ownerCtx->getAsDecl();
478481
auto &ctx = decl->getASTContext();
479-
if (gp->isParameterPack() && isa<GenericTypeDecl>(decl) &&
480-
!ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
481-
decl->diagnose(diag::experimental_type_with_parameter_pack);
482+
if (gp->isParameterPack() && isGenericType) {
483+
if (!ctx.LangOpts.hasFeature(Feature::VariadicGenerics)) {
484+
decl->diagnose(diag::experimental_type_with_parameter_pack);
485+
}
486+
487+
if (hasPack) {
488+
gp->diagnose(diag::more_than_one_parameter_pack_in_type);
489+
}
490+
491+
hasPack = true;
482492
}
483493

484494
TypeChecker::checkDeclAttributes(gp);

test/Constraints/pack-expansion-expressions.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,28 @@ func returnEachPackReference<each T>(_ t: repeat each T) -> each T { // expected
103103
fatalError()
104104
}
105105

106-
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{63-63=each }}
106+
// expected-error@+1 {{type pack 'T' must be referenced with 'each'}}{{63-63=each }}
107107
func returnRepeatTuple<each T>(_ t: repeat each T) -> (repeat T) {
108108
fatalError()
109109
}
110110

111111
// expected-error@+2 {{pack reference 'T' requires expansion using keyword 'repeat'}}
112-
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{55-55=each }}
112+
// expected-error@+1 {{type pack 'T' must be referenced with 'each'}}{{55-55=each }}
113113
func parameterAsPackTypeWithoutExpansion<each T>(_ t: T) {
114114
}
115115

116116
// expected-error@+2 {{pack reference 'T' requires expansion using keyword 'repeat'}}
117-
// expected-error@+1 {{pack type 'T' must be referenced with 'each'}}{{57-57=each }}
117+
// expected-error@+1 {{type pack 'T' must be referenced with 'each'}}{{57-57=each }}
118118
func returnPackReference<each T>(_ t: repeat each T) -> T {
119119
fatalError()
120120
}
121121

122122
func packTypeParameterOutsidePackExpansionType<each T>(_ t: T,
123123
// expected-error@-1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
124-
// expected-error@-2 {{pack type 'T' must be referenced with 'each'}}{{61-61=each }}
124+
// expected-error@-2 {{type pack 'T' must be referenced with 'each'}}{{61-61=each }}
125125
_ a: Array<T>) {
126126
// expected-error@-1 {{pack reference 'T' requires expansion using keyword 'repeat'}}
127-
// expected-error@-2 {{pack type 'T' must be referenced with 'each'}}{{67-67=each }}
127+
// expected-error@-2 {{type pack 'T' must be referenced with 'each'}}{{67-67=each }}
128128
}
129129

130130
func expansionOfNonPackType<T>(_ t: repeat each T) {}

test/Generics/variadic_generic_types.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
// REQUIRES: asserts
44

5+
struct MultiplePack<each T, each U> {} // expected-error {{generic type cannot have more than one pack}}
6+
typealias MultiplePackAlias<each T, each U> = (repeat each T, repeat each U) // expected-error {{generic type cannot have more than one pack}}
7+
58
func bindAll() {
69
struct Bind<each U> {}
710

0 commit comments

Comments
 (0)