Skip to content

Commit 8f3a91e

Browse files
authored
Merge pull request #65769 from slavapestov/variadic-generic-diagnostics-5.9
Variadic generic diagnostics [5.9]
2 parents d03f910 + a54865f commit 8f3a91e

File tree

5 files changed

+74
-11
lines changed

5 files changed

+74
-11
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5406,6 +5406,12 @@ ERROR(vararg_not_allowed,none,
54065406
ERROR(experimental_type_with_parameter_pack,none,
54075407
"generic types with parameter packs are experimental",
54085408
())
5409+
ERROR(more_than_one_pack_in_type,none,
5410+
"generic type cannot declare more than one type pack", ())
5411+
ERROR(enum_with_pack,none,
5412+
"enums cannot declare a type pack", ())
5413+
ERROR(superclass_with_pack,none,
5414+
"cannot inherit from a generic class that declares a type pack", ())
54095415
ERROR(expansion_not_allowed,none,
54105416
"pack expansion %0 can only appear in a function parameter list, "
54115417
"tuple element, or generic argument list", (Type))
@@ -5427,7 +5433,7 @@ ERROR(pack_reference_must_be_in_expansion,none,
54275433
"pack reference %0 requires expansion using keyword 'repeat'",
54285434
(TypeRepr*))
54295435
ERROR(pack_type_requires_keyword_each,none,
5430-
"pack type %0 must be referenced with 'each'",
5436+
"type pack %0 must be referenced with 'each'",
54315437
(TypeRepr*))
54325438
ERROR(tuple_duplicate_label,none,
54335439
"cannot create a tuple with a duplicate element label", ())

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 37 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_pack_in_type);
489+
}
490+
491+
hasPack = true;
482492
}
483493

484494
TypeChecker::checkDeclAttributes(gp);
@@ -2545,6 +2555,17 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
25452555
void visitEnumDecl(EnumDecl *ED) {
25462556
checkUnsupportedNestedType(ED);
25472557

2558+
// Temporary restriction until we figure out pattern matching and
2559+
// enum case construction with packs.
2560+
if (auto genericSig = ED->getGenericSignature()) {
2561+
for (auto paramTy : genericSig.getGenericParams()) {
2562+
if (paramTy->isParameterPack()) {
2563+
ED->diagnose(diag::enum_with_pack);
2564+
break;
2565+
}
2566+
}
2567+
}
2568+
25482569
// FIXME: Remove this once we clean up the mess involving raw values.
25492570
(void) ED->getInterfaceType();
25502571

@@ -2824,6 +2845,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
28242845
else if (superclass->isActor())
28252846
CD->diagnose(diag::actor_inheritance,
28262847
/*distributed=*/CD->isDistributedActor());
2848+
2849+
// Enforce a temporary restriction on inheriting from a superclass
2850+
// type with a pack, until we figure out the semantics of method
2851+
// overrides in these situations.
2852+
if (auto genericSig = superclass->getGenericSignature()) {
2853+
for (auto paramTy : genericSig.getGenericParams()) {
2854+
if (paramTy->isParameterPack()) {
2855+
CD->diagnose(diag::superclass_with_pack);
2856+
break;
2857+
}
2858+
}
2859+
}
28272860
}
28282861

28292862
if (CD->isDistributedActor()) {

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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics
22

3+
// Because of -enable-experimental-feature VariadicGenerics
34
// REQUIRES: asserts
45

6+
// Disallowed cases
7+
struct MultiplePack<each T, each U> {} // expected-error {{generic type cannot declare more than one type pack}}
8+
typealias MultiplePackAlias<each T, each U> = (repeat each T, repeat each U) // expected-error {{generic type cannot declare more than one type pack}}
9+
10+
// Temporary limitations
11+
enum EnumWithPack<each T> { // expected-error {{enums cannot declare a type pack}}
12+
case cheddar
13+
}
14+
15+
class ClassWithPack<each T> {}
16+
17+
struct OuterStruct<each T> {
18+
enum NestedEnum { // expected-error {{enums cannot declare a type pack}}
19+
case smokedGouda
20+
}
21+
22+
class NestedClass {}
23+
}
24+
25+
class BadInheritance1: ClassWithPack<Int> {} // expected-error {{cannot inherit from a generic class that declares a type pack}}
26+
class BadInheritance2: OuterStruct<Int>.NestedClass {} // expected-error {{cannot inherit from a generic class that declares a type pack}}
27+
28+
// Type resolution of variadic type aliases
529
func bindAll() {
630
struct Bind<each U> {}
731

test/type/pack_expansion.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func f5<each T>() -> () -> (repeat each T) {}
3030

3131
func f6<each T>() -> (repeat each T) -> () {}
3232

33-
enum E<each T> {
33+
enum E<each T> { // expected-error {{enums cannot declare a type pack}}
3434
case f1(_: repeat each T)
3535

3636
case f2(_: G<repeat each T>)

0 commit comments

Comments
 (0)