Skip to content

Commit 8ea7fff

Browse files
Using BacktrackingScope to fix expected pattern
1 parent 6edb69a commit 8ea7fff

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5767,32 +5767,32 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
57675767
SourceLoc TokLoc = Tok.getLoc();
57685768
StringRef TokText = Tok.getText();
57695769

5770-
if (!NameIsKeyword || Tok.isIdentifierOrUnderscore()) {
5771-
// For recovery, see if the user typed something resembling a switch
5772-
// "case" label.
5770+
// For recovery, see if the user typed something resembling a switch
5771+
// "case" label.
5772+
{
5773+
BacktrackingScope backtrack(*this);
57735774
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
57745775
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
57755776
parseMatchingPattern(/*isExprBasic*/false);
5777+
5778+
if (consumeIf(tok::colon)) {
5779+
backtrack.cancelBacktrack();
5780+
diagnose(CaseLoc, diag::case_outside_of_switch, "case");
5781+
Status.setIsParseError();
5782+
return Status;
5783+
}
57765784
}
5777-
5778-
if (consumeIf(tok::colon)) {
5779-
diagnose(CaseLoc, diag::case_outside_of_switch, "case");
5785+
if (CommaLoc.isValid() && !NameIsKeyword) {
5786+
diagnose(CommaLoc, diag::expected_identifier_after_case_comma);
57805787
Status.setIsParseError();
57815788
return Status;
5782-
}
5783-
5784-
if (NameIsKeyword) {
5789+
} else if (NameIsKeyword) {
57855790
diagnose(TokLoc, diag::keyword_cant_be_identifier, TokText);
57865791
diagnose(TokLoc, diag::backticks_to_escape)
57875792
.fixItReplace(TokLoc, "`" + TokText.str() + "`");
57885793
if (!Tok.isAtStartOfLine())
57895794
consumeToken();
57905795
} else {
5791-
if (CommaLoc.isValid()) {
5792-
diagnose(Tok, diag::expected_identifier_after_case_comma);
5793-
Status.setIsParseError();
5794-
return Status;
5795-
}
57965796
diagnose(CaseLoc, diag::expected_identifier_in_decl, "enum 'case'");
57975797
}
57985798
}

test/Parse/enum.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ enum Recovery5 {
127127
enum Recovery6 {
128128
case Snout, _; // expected-error {{keyword '_' cannot be used as an identifier here}} expected-note {{if this name is unavoidable, use backticks to escape it}} {{15-16=`_`}}
129129
case _; // expected-error {{keyword '_' cannot be used as an identifier here}} expected-note {{if this name is unavoidable, use backticks to escape it}} {{8-9=`_`}}
130-
case Tusk, // expected-error {{expected pattern}}
131-
} // expected-error {{expected identifier after comma in enum 'case' declaration}}
130+
case Tusk, // expected-error {{expected identifier after comma in enum 'case' declaration}}
131+
}
132132

133133
enum RawTypeEmpty : Int {} // expected-error {{an enum with no cases cannot declare a raw type}} expected-note {{do you want to add protocol stubs?}}
134134
// expected-error@-1{{'RawTypeEmpty' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}}
@@ -574,4 +574,8 @@ enum SR11261_Newline {
574574
enum SR11261_Newline2 {
575575
case
576576
func foo() {} // expected-error {{keyword 'func' cannot be used as an identifier here}} expected-note {{if this name is unavoidable, use backticks to escape it}} {{3-7=`func`}}
577+
}
578+
579+
enum SR11261_PatternMatching {
580+
case let .foo(x, y): // expected-error {{'case' label can only appear inside a 'switch' statement}}
577581
}

0 commit comments

Comments
 (0)