Skip to content

Commit f8f147e

Browse files
[DiagnosticsQoI] SR-3600: Better recovery for trying to name an initializer, deinitializer, or subscript
- Restrict this diagnostic to identifiers that are followed by a left paren.
1 parent 7882ddc commit f8f147e

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5517,10 +5517,8 @@ parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
55175517
if (!Tok.is(tok::l_brace) && !isInSILMode()) {
55185518
if (Tok.is(tok::identifier)) {
55195519
diagnose(Tok, diag::destructor_has_name).fixItRemove(Tok.getLoc());
5520-
}
5521-
else {
5520+
} else
55225521
diagnose(Tok, diag::expected_lbrace_destructor);
5523-
}
55245522
return nullptr;
55255523
}
55265524
}

lib/Parse/ParsePattern.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,14 @@ Parser::parseSingleParameterClause(ParameterContextKind paramContext,
483483
diagID = diag::func_decl_without_paren;
484484
break;
485485
case ParameterContextKind::Subscript:
486-
skipIdentifier = Tok.is(tok::identifier);
486+
skipIdentifier = Tok.is(tok::identifier) &&
487+
peekToken().is(tok::l_paren);
487488
diagID = skipIdentifier ? diag::subscript_has_name
488489
: diag::expected_lparen_subscript;
489490
break;
490491
case ParameterContextKind::Initializer:
491-
skipIdentifier = Tok.is(tok::identifier);
492+
skipIdentifier = Tok.is(tok::identifier) &&
493+
peekToken().is(tok::l_paren);
492494
diagID = skipIdentifier ? diag::initializer_has_name
493495
: diag::expected_lparen_initializer;
494496
break;

test/Parse/recovery.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,18 @@ struct InitializerWithName {
541541
init x() {} // expected-error {{initializers cannot have a name}} {{8-9=}}
542542
}
543543

544+
struct InitializerWithNameAndParam {
545+
init a(b: Int) {} // expected-error {{initializers cannot have a name}} {{8-9=}}
546+
}
547+
548+
struct InitializerWithLabels {
549+
init c d: Int {}
550+
// expected-error @-1 {{expected '(' for initializer parameters}}
551+
// expected-error @-2 {{expected declaration}}
552+
// expected-error @-3 {{consecutive declarations on a line must be separated by ';'}}
553+
// expected-note @-5 {{in declaration of 'InitializerWithLabels'}}
554+
}
555+
544556
// rdar://20337695
545557
func f1() {
546558

test/Parse/subscripting.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ _ = y2[0] // expected-error{{cannot use mutating getter on immutable value: 'y2'
8181

8282
// Parsing errors
8383
struct A0 {
84-
subscript // expected-error {{subscripts cannot have a name}} {{5-7=}}
84+
subscript // expected-error {{expected '(' for subscript parameters}}
8585
i : Int
8686
-> Int {
8787
get {
@@ -175,4 +175,23 @@ struct A8 {
175175
stored = value
176176
}
177177
}
178+
179+
struct A9 {
180+
subscript x() -> Int { // expected-error {{subscripts cannot have a name}} {{13-14=}}
181+
return 0
182+
}
183+
}
184+
185+
struct A10 {
186+
subscript x(i: Int) -> Int { // expected-error {{subscripts cannot have a name}} {{13-14=}}
187+
return 0
188+
}
189+
}
190+
191+
struct A11 {
192+
subscript x y : Int -> Int { // expected-error {{expected '(' for subscript parameters}}
193+
return 0
194+
}
195+
}
196+
178197
} // expected-error{{extraneous '}' at top level}} {{1-3=}}

0 commit comments

Comments
 (0)