Skip to content

Commit 5e35adc

Browse files
authored
Merge pull request swiftlang#28951 from kitaisreal/separated-do-while-blocks-diagnostic-correction
[Parse]: Separate do and while blocks diagnostics
2 parents 716c72c + f40a67d commit 5e35adc

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,11 @@ ERROR(expected_expr_repeat_while,PointsToFirstBadToken,
10371037
"expected expression in 'repeat-while' condition", ())
10381038

10391039
ERROR(do_while_now_repeat_while,none,
1040-
"'do-while' statement is not allowed; use 'repeat-while' instead", ())
1040+
"'do-while' statement is not allowed", ())
1041+
NOTE(do_while_expected_repeat_while, none,
1042+
"did you mean 'repeat-while' statement?", ())
1043+
NOTE(do_while_expected_separate_stmt, none,
1044+
"did you mean separate 'do' and 'while' statements?", ())
10411045

10421046
// Do/Catch Statement
10431047
ERROR(expected_lbrace_after_do,PointsToFirstBadToken,

lib/Parse/ParseStmt.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,18 +1917,21 @@ ParserResult<Stmt> Parser::parseStmtDo(LabeledStmtInfo labelInfo) {
19171917
DoCatchStmt::create(Context, labelInfo, doLoc, body.get(), allClauses));
19181918
}
19191919

1920-
SourceLoc whileLoc;
1921-
1922-
// If we don't see a 'while', this is just the bare 'do' scoping
1923-
// statement.
1924-
if (!consumeIf(tok::kw_while, whileLoc)) {
1920+
// If we dont see a 'while' or see a 'while' that starts
1921+
// from new line. This is just the bare `do` scoping statement.
1922+
if (Tok.getKind() != tok::kw_while || Tok.isAtStartOfLine()) {
19251923
return makeParserResult(status,
1926-
new (Context) DoStmt(labelInfo, doLoc, body.get()));
1924+
new (Context) DoStmt(labelInfo, doLoc, body.get()));
19271925
}
1928-
1926+
SourceLoc whileLoc = Tok.getLoc();
19291927
// But if we do, advise the programmer that it's 'repeat' now.
1930-
diagnose(doLoc, diag::do_while_now_repeat_while)
1928+
diagnose(doLoc, diag::do_while_now_repeat_while);
1929+
diagnose(doLoc, diag::do_while_expected_repeat_while)
19311930
.fixItReplace(doLoc, "repeat");
1931+
diagnose(doLoc, diag::do_while_expected_separate_stmt)
1932+
.fixItInsert(whileLoc, "\n");
1933+
1934+
consumeToken(tok::kw_while);
19321935
status.setIsParseError();
19331936
ParserResult<Expr> condition;
19341937
if (Tok.is(tok::l_brace)) {

test/stmt/statements.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,23 @@ func DoStmt() {
235235
}
236236
}
237237

238-
func DoWhileStmt() {
239-
do { // expected-error {{'do-while' statement is not allowed; use 'repeat-while' instead}} {{3-5=repeat}}
238+
239+
func DoWhileStmt1() {
240+
do { // expected-error {{'do-while' statement is not allowed}}
241+
// expected-note@-1 {{did you mean 'repeat-while' statement?}} {{3-5=repeat}}
242+
// expected-note@-2 {{did you mean separate 'do' and 'while' statements?}} {{5-5=\n}}
240243
} while true
241244
}
242245

246+
func DoWhileStmt2() {
247+
do {
248+
249+
}
250+
while true {
251+
252+
}
253+
}
254+
243255
//===--- Repeat-while statement.
244256

245257
func RepeatWhileStmt1() {

0 commit comments

Comments
 (0)