Skip to content

Commit f787e1b

Browse files
committed
[Statement checker] Simplify checkUnknownAttrRestrictions().
This routine can compute the fallthrough destination on its own. When it does, we start correctly checking @unknown cases in function builders, so update and expand the test accordingly.
1 parent 336160a commit f787e1b

File tree

4 files changed

+19
-10
lines changed

4 files changed

+19
-10
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,8 +1348,7 @@ class BuilderClosureRewriter
13481348
// Check restrictions on '@unknown'.
13491349
if (caseStmt->hasUnknownAttr()) {
13501350
checkUnknownAttrRestrictions(
1351-
cs.getASTContext(), caseStmt, /*fallthroughDest=*/nullptr,
1352-
limitExhaustivityChecks);
1351+
cs.getASTContext(), caseStmt, limitExhaustivityChecks);
13531352
}
13541353

13551354
++caseIndex;

lib/Sema/TypeCheckStmt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,8 +1236,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
12361236
assert(parentKind == CaseParentKind::Switch &&
12371237
"'@unknown' can only appear on switch cases");
12381238
checkUnknownAttrRestrictions(
1239-
getASTContext(), caseBlock, FallthroughDest,
1240-
limitExhaustivityChecks);
1239+
getASTContext(), caseBlock, limitExhaustivityChecks);
12411240
}
12421241

12431242
Stmt *body = caseBlock->getBody();
@@ -2157,8 +2156,9 @@ void TypeChecker::typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {
21572156
}
21582157

21592158
void swift::checkUnknownAttrRestrictions(
2160-
ASTContext &ctx, CaseStmt *caseBlock, CaseStmt *fallthroughDest,
2159+
ASTContext &ctx, CaseStmt *caseBlock,
21612160
bool &limitExhaustivityChecks) {
2161+
CaseStmt *fallthroughDest = caseBlock->findNextCaseStmt();
21622162
if (caseBlock->getCaseLabelItems().size() != 1) {
21632163
assert(!caseBlock->getCaseLabelItems().empty() &&
21642164
"parser should not produce case blocks with no items");

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,7 @@ bool areGenericRequirementsSatisfied(const DeclContext *DC,
13771377
/// Check for restrictions on the use of the @unknown attribute on a
13781378
/// case statement.
13791379
void checkUnknownAttrRestrictions(
1380-
ASTContext &ctx, CaseStmt *caseBlock, CaseStmt *fallthroughDest,
1381-
bool &limitExhaustivityChecks);
1380+
ASTContext &ctx, CaseStmt *caseBlock, bool &limitExhaustivityChecks);
13821381

13831382
/// Bind all of the pattern variables that occur within a case statement and
13841383
/// all of its case items to their "parent" pattern variables, forming chains

test/Constraints/function_builder_diags.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,16 +433,27 @@ struct TestConstraintGenerationErrors {
433433

434434
// Check @unknown
435435
func testUnknownInSwitchSwitch(e: E) {
436-
tuplify(true) { c in
436+
tuplify(true) { c in
437437
"testSwitch"
438438
switch e {
439-
@unknown case .a: // expected-error{{'@unknown' is only supported for catch-all cases ("case _")}}
440-
"a"
441439
case .b(let i, let s?):
442440
i * 2
443441
s + "!"
444442
default:
445443
"nothing"
444+
@unknown case .a: // expected-error{{'@unknown' is only supported for catch-all cases ("case _")}}
445+
// expected-error@-1{{'case' blocks cannot appear after the 'default' block of a 'switch'}}
446+
"a"
447+
}
448+
}
449+
450+
tuplify(true) { c in
451+
"testSwitch"
452+
switch e {
453+
@unknown case _: // expected-error{{'@unknown' can only be applied to the last case in a switch}}
454+
"a"
455+
default:
456+
"default"
446457
}
447458
}
448459
}

0 commit comments

Comments
 (0)