Skip to content

Commit bca451b

Browse files
committed
[Sema] Improve diagnostic for empty if expr branch
Previously we would say that it must end with a `throw`, but a more useful diagnostic is that there is an expression missing.
1 parent 48b58eb commit bca451b

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,9 @@ ERROR(single_value_stmt_must_be_unlabeled,none,
11431143
ERROR(if_expr_must_be_syntactically_exhaustive,none,
11441144
"'if' must have an unconditional 'else' to be used as expression",
11451145
())
1146+
ERROR(single_value_stmt_branch_empty,none,
1147+
"expected expression in branch of '%0' expression",
1148+
(StmtKind))
11461149
ERROR(single_value_stmt_branch_must_end_in_throw,none,
11471150
"non-expression branch of '%0' expression may only end with a 'throw'",
11481151
(StmtKind))

lib/Sema/MiscDiagnostics.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3878,6 +3878,14 @@ class SingleValueStmtUsageChecker final : public ASTWalker {
38783878
break;
38793879
case IsSingleValueStmtResult::Kind::UnterminatedBranches: {
38803880
for (auto *branch : mayProduceSingleValue.getUnterminatedBranches()) {
3881+
if (auto *BS = dyn_cast<BraceStmt>(branch)) {
3882+
if (BS->empty()) {
3883+
Diags.diagnose(branch->getStartLoc(),
3884+
diag::single_value_stmt_branch_empty,
3885+
S->getKind());
3886+
continue;
3887+
}
3888+
}
38813889
Diags.diagnose(branch->getEndLoc(),
38823890
diag::single_value_stmt_branch_must_end_in_throw,
38833891
S->getKind());

test/expr/unary/if_expr.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,12 @@ func nestedType() -> Int {
646646
}
647647
}
648648

649+
func testEmptyBranch() -> Int {
650+
let x = if .random() {} else { 0 }
651+
// expected-error@-1:24 {{expected expression in branch of 'if' expression}}
652+
return x
653+
}
654+
649655
// MARK: Jumping
650656

651657
func break1() -> Int {

test/expr/unary/switch_expr.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,21 @@ func nestedType() -> Int {
859859
}
860860
}
861861

862+
func testEmptyBranch() -> Int {
863+
// TODO: Ideally we wouldn't emit both diagnostics, the latter is the better
864+
// one, but the former is currently emitted by the parser. Ideally the former
865+
// one should become semantic, and we'd just avoid it for
866+
// SingleValueStmtExprs.
867+
let x = switch Bool.random() {
868+
case true:
869+
// expected-error@-1 {{'case' label in a 'switch' must have at least one executable statement}}
870+
// expected-error@-2:14 {{expected expression in branch of 'switch' expression}}
871+
case false:
872+
0
873+
}
874+
return x
875+
}
876+
862877
// MARK: Jumping
863878

864879
func break1() -> Int {

0 commit comments

Comments
 (0)