Skip to content

Commit d27765e

Browse files
authored
Merge pull request swiftlang#18904 from CodaFi/filling-the-void-within-my-soul
[SE-0155] Reject empty associated value lists
2 parents 218f1e7 + e12fbc2 commit d27765e

File tree

8 files changed

+45
-8
lines changed

8 files changed

+45
-8
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,18 @@ ERROR(initializer_as_typed_pattern,none,
866866
ERROR(unlabeled_parameter_following_variadic_parameter,none,
867867
"a parameter following a variadic parameter requires a label", ())
868868

869+
ERROR(enum_element_empty_arglist,none,
870+
"enum element with associated values must have at least one "
871+
"associated value", ())
872+
WARNING(enum_element_empty_arglist_swift4,none,
873+
"enum element with associated values must have at least one "
874+
"associated value; this will be an error in the future "
875+
"version of Swift", ())
876+
NOTE(enum_element_empty_arglist_delete,none,
877+
"did you mean to remove the empty associated value list?", ())
878+
NOTE(enum_element_empty_arglist_add_void,none,
879+
"did you mean to explicitly add a 'Void' associated value?", ())
880+
869881
//------------------------------------------------------------------------------
870882
// Statement parsing diagnostics
871883
//------------------------------------------------------------------------------

lib/Parse/ParsePattern.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,23 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
169169
SyntaxKind::FunctionParameterList);
170170
}
171171
rightParenLoc = consumeToken(tok::r_paren);
172+
173+
// Per SE-0155, enum elements may not have empty parameter lists.
174+
if (paramContext == ParameterContextKind::EnumElement) {
175+
decltype(diag::enum_element_empty_arglist) diagnostic;
176+
if (Context.isSwiftVersionAtLeast(5)) {
177+
diagnostic = diag::enum_element_empty_arglist;
178+
} else {
179+
diagnostic = diag::enum_element_empty_arglist_swift4;
180+
}
181+
182+
diagnose(leftParenLoc, diagnostic)
183+
.highlight({leftParenLoc, rightParenLoc});
184+
diagnose(leftParenLoc, diag::enum_element_empty_arglist_delete)
185+
.fixItRemoveChars(leftParenLoc, rightParenLoc);
186+
diagnose(leftParenLoc, diag::enum_element_empty_arglist_add_void)
187+
.fixItInsert(leftParenLoc, "Void");
188+
}
172189
return ParserStatus();
173190
}
174191

test/IRGen/enum_empty_payloads.sil

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir -verify %s
22
sil_stage canonical
33

4+
typealias Void = ()
5+
46
struct Empty<T> {}
57

68
enum SinglePayload<T> {
79
case A(T)
8-
case B()
10+
case B(Void)
911
case C(Empty<T>)
1012
}
1113

1214
enum MultiPayload<T, U> {
1315
case A(T)
1416
case B(U)
15-
case C()
16-
case D()
17+
case C(Void)
18+
case D(Void)
1719
case E(Empty<T>)
1820
case F(Empty<U>)
1921
}

test/Parse/enum.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ enum Recovery2 {
110110
case UE1: // expected-error {{'case' label can only appear inside a 'switch' statement}}
111111
}
112112
enum Recovery3 {
113-
case UE2(): // expected-error {{'case' label can only appear inside a 'switch' statement}}
113+
case UE2(Void): // expected-error {{'case' label can only appear inside a 'switch' statement}}
114114
}
115115
enum Recovery4 { // expected-note {{in declaration of 'Recovery4'}}
116116
case Self Self // expected-error {{keyword 'Self' cannot be used as an identifier here}} expected-note {{if this name is unavoidable, use backticks to escape it}} {{8-12=`Self`}} expected-error {{consecutive declarations on a line must be separated by ';'}} {{12-12=;}} expected-error {{expected declaration}}
@@ -542,3 +542,9 @@ enum SE0036_Generic<T> {
542542
}
543543

544544
enum switch {} // expected-error {{keyword 'switch' cannot be used as an identifier here}} expected-note {{if this name is unavoidable, use backticks to escape it}} {{6-12=`switch`}}
545+
546+
enum SE0155 {
547+
case emptyArgs() // expected-warning {{enum element with associated values must have at least one associated value}}
548+
// expected-note@-1 {{did you mean to remove the empty associated value list?}} {{17-18=}}
549+
// expected-note@-2 {{did you mean to explicitly add a 'Void' associated value?}} {{17-17=Void}}
550+
}

test/SIL/Parser/undef.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct S {
2121

2222
enum E {
2323
case Case
24-
case DataCase(())
24+
case DataCase(Void)
2525
}
2626

2727
sil @general_test : $() -> () {

test/SILOptimizer/definite_init_diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ func testOptionalWriteGenerics2<T>(p: T) -> T? {
14261426

14271427
enum TestOptionalEnum {
14281428
case Cons(Int)
1429-
case Nil()
1429+
case Nil
14301430
}
14311431

14321432
func testOptionalWithEnum(p: TestOptionalEnum) -> TestOptionalEnum? {

test/SILOptimizer/loweraggregateinstrs.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct S {
3737
}
3838

3939
enum E {
40-
case NoElement()
40+
case NoElement
4141
case TrivialElement(Builtin.Int64)
4242
case ReferenceElement(C1)
4343
case StructNonTrivialElt(S)

test/attr/attr_autoclosure.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class TestFunc12 {
125125

126126
enum AutoclosureFailableOf<T> {
127127
case Success(@autoclosure () -> T)
128-
case Failure()
128+
case Failure
129129
}
130130

131131
let _ : AutoclosureFailableOf<Int> = .Success(42)

0 commit comments

Comments
 (0)