Skip to content

Commit 483fc05

Browse files
authored
Merge pull request #25898 from gregomni/sr-10946
Improve diagnostic for unexpected ']' while parsing a type.
2 parents ef0f7dc + c86017e commit 483fc05

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,10 @@ ERROR(expected_dictionary_value_type,PointsToFirstBadToken,
758758
"expected dictionary value type", ())
759759
ERROR(expected_rbracket_dictionary_type,PointsToFirstBadToken,
760760
"expected ']' in dictionary type", ())
761+
ERROR(extra_rbracket,PointsToFirstBadToken,
762+
"unexpected ']' in type; did you mean to write an array type?", ())
763+
ERROR(extra_colon,PointsToFirstBadToken,
764+
"unexpected ':' in type; did you mean to write a dictionary type?", ())
761765

762766
// Tuple Types
763767
ERROR(expected_rparen_tuple_type_list,none,

lib/Parse/ParseType.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,30 @@ ParserResult<TypeRepr> Parser::parseDeclResultType(Diag<> MessageID) {
520520
consumeToken(tok::code_complete);
521521
return makeParserCodeCompletionStatus();
522522
}
523-
return parseType(MessageID);
523+
524+
auto result = parseType(MessageID);
525+
526+
if (!result.isParseError() && Tok.is(tok::r_square)) {
527+
auto diag = diagnose(Tok, diag::extra_rbracket);
528+
diag.fixItInsert(result.get()->getStartLoc(), getTokenText(tok::l_square));
529+
consumeToken();
530+
return makeParserErrorResult(new (Context) ErrorTypeRepr(Tok.getLoc()));
531+
} else if (!result.isParseError() && Tok.is(tok::colon)) {
532+
auto colonTok = consumeToken();
533+
auto secondType = parseType(diag::expected_dictionary_value_type);
534+
535+
auto diag = diagnose(colonTok, diag::extra_colon);
536+
diag.fixItInsert(result.get()->getStartLoc(), getTokenText(tok::l_square));
537+
if (!secondType.isParseError()) {
538+
if (Tok.is(tok::r_square)) {
539+
consumeToken();
540+
} else {
541+
diag.fixItInsertAfter(secondType.get()->getEndLoc(), getTokenText(tok::r_square));
542+
}
543+
}
544+
return makeParserErrorResult(new (Context) ErrorTypeRepr(Tok.getLoc()));
545+
}
546+
return result;
524547
}
525548

526549
ParserStatus Parser::parseGenericArguments(SmallVectorImpl<TypeRepr *> &Args,

test/Parse/recovery.swift

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ protocol FooProtocol {}
88

99
func garbage() -> () {
1010
var a : Int
11-
] this line is invalid, but we will stop at the keyword below... // expected-error{{expected expression}}
11+
) this line is invalid, but we will stop at the keyword below... // expected-error{{expected expression}}
1212
return a + "a" // expected-error{{binary operator '+' cannot be applied to operands of type 'Int' and 'String'}} expected-note {{overloads for '+' exist with these partially matching parameter lists: (Int, Int), (String, String)}}
1313
}
1414

@@ -435,8 +435,8 @@ struct ErrorTypeInVarDeclFunctionType1 {
435435
var v2 : Int
436436
}
437437

438-
struct ErrorTypeInVarDeclArrayType1 { // expected-note{{in declaration of 'ErrorTypeInVarDeclArrayType1'}}
439-
var v1 : Int[+] // expected-error {{expected declaration}} expected-error {{consecutive declarations on a line must be separated by ';'}}
438+
struct ErrorTypeInVarDeclArrayType1 {
439+
var v1 : Int[+] // expected-error {{unexpected ']' in type; did you mean to write an array type?}}
440440
// expected-error @-1 {{expected expression after unary operator}}
441441
// expected-error @-2 {{expected expression}}
442442
var v2 : Int
@@ -455,13 +455,36 @@ struct ErrorTypeInVarDeclArrayType3 {
455455

456456
struct ErrorTypeInVarDeclArrayType4 {
457457
var v1 : Int[1 // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}}
458+
var v2 : Int] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{12-12=[}}
458459

459460
}
460461

462+
struct ErrorTypeInVarDeclArrayType5 { // expected-note {{in declaration of 'ErrorTypeInVarDeclArrayType5'}}
463+
let a1: Swift.Int] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
464+
let a2: Set<Int]> // expected-error {{expected '>' to complete generic argument list}} // expected-note {{to match this opening '<'}}
465+
let a3: Set<Int>] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
466+
let a4: Int]? // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
467+
// expected-error @-1 {{consecutive declarations on a line must be separated by ';'}} // expected-error @-1 {{expected declaration}}
468+
let a5: Int?] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
469+
let a6: [Int]] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
470+
let a7: [String: Int]] // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{11-11=[}}
471+
}
472+
473+
struct ErrorTypeInVarDeclDictionaryType {
474+
let a1: String: // expected-error {{unexpected ':' in type; did you mean to write a dictionary type?}} {{11-11=[}}
475+
// expected-error @-1 {{expected dictionary value type}}
476+
let a2: String: Int] // expected-error {{unexpected ':' in type; did you mean to write a dictionary type?}} {{11-11=[}}
477+
let a3: String: [Int] // expected-error {{unexpected ':' in type; did you mean to write a dictionary type?}} {{11-11=[}} {{24-24=]}}
478+
let a4: String: Int // expected-error {{unexpected ':' in type; did you mean to write a dictionary type?}} {{11-11=[}} {{22-22=]}}
479+
}
480+
461481
struct ErrorInFunctionSignatureResultArrayType1 {
462482
func foo() -> Int[ { // expected-error {{expected '{' in body of function declaration}}
463483
return [0]
464484
}
485+
func bar() -> Int] { // expected-error {{unexpected ']' in type; did you mean to write an array type?}} {{17-17=[}}
486+
return [0]
487+
}
465488
}
466489

467490
struct ErrorInFunctionSignatureResultArrayType2 {

0 commit comments

Comments
 (0)