Skip to content

Commit 8d3d952

Browse files
committed
[gardening] Extract out checking of fallthrough pattern bindings and types into its own helper method.
This is the last "subroutine" I am extracting from StmtChecker::visitSwitchStmt. It is possible to read easily now without getting lost.
1 parent f241f10 commit 8d3d952

File tree

1 file changed

+38
-30
lines changed

1 file changed

+38
-30
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,43 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10461046
}
10471047
}
10481048

1049+
void checkFallthroughPatternBindingsAndTypes(CaseStmt *caseBlock,
1050+
CaseStmt *previousBlock) {
1051+
auto firstPattern = caseBlock->getCaseLabelItems()[0].getPattern();
1052+
SmallVector<VarDecl *, 4> vars;
1053+
firstPattern->collectVariables(vars);
1054+
1055+
for (auto &labelItem : previousBlock->getCaseLabelItems()) {
1056+
const Pattern *pattern = labelItem.getPattern();
1057+
SmallVector<VarDecl *, 4> PreviousVars;
1058+
pattern->collectVariables(PreviousVars);
1059+
for (auto expected : vars) {
1060+
bool matched = false;
1061+
if (!expected->hasName())
1062+
continue;
1063+
for (auto previous : PreviousVars) {
1064+
if (previous->hasName() &&
1065+
expected->getName() == previous->getName()) {
1066+
if (!previous->getType()->isEqual(expected->getType())) {
1067+
TC.diagnose(previous->getLoc(),
1068+
diag::type_mismatch_fallthrough_pattern_list,
1069+
previous->getType(), expected->getType());
1070+
previous->markInvalid();
1071+
expected->markInvalid();
1072+
}
1073+
matched = true;
1074+
break;
1075+
}
1076+
}
1077+
if (!matched) {
1078+
TC.diagnose(PreviousFallthrough->getLoc(),
1079+
diag::fallthrough_into_case_with_var_binding,
1080+
expected->getName());
1081+
}
1082+
}
1083+
}
1084+
}
1085+
10491086
Stmt *visitSwitchStmt(SwitchStmt *switchStmt) {
10501087
// Type-check the subject expression.
10511088
Expr *subjectExpr = switchStmt->getSubjectExpr();
@@ -1092,36 +1129,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10921129
// If the previous case fellthrough, similarly check that that case's bindings
10931130
// includes our first label item's pattern bindings and types.
10941131
if (PreviousFallthrough && previousBlock) {
1095-
auto firstPattern = caseBlock->getCaseLabelItems()[0].getPattern();
1096-
SmallVector<VarDecl *, 4> vars;
1097-
firstPattern->collectVariables(vars);
1098-
1099-
for (auto &labelItem : previousBlock->getCaseLabelItems()) {
1100-
const Pattern *pattern = labelItem.getPattern();
1101-
SmallVector<VarDecl *, 4> PreviousVars;
1102-
pattern->collectVariables(PreviousVars);
1103-
for (auto expected : vars) {
1104-
bool matched = false;
1105-
if (!expected->hasName())
1106-
continue;
1107-
for (auto previous: PreviousVars) {
1108-
if (previous->hasName() && expected->getName() == previous->getName()) {
1109-
if (!previous->getType()->isEqual(expected->getType())) {
1110-
TC.diagnose(previous->getLoc(), diag::type_mismatch_fallthrough_pattern_list,
1111-
previous->getType(), expected->getType());
1112-
previous->markInvalid();
1113-
expected->markInvalid();
1114-
}
1115-
matched = true;
1116-
break;
1117-
}
1118-
}
1119-
if (!matched) {
1120-
TC.diagnose(PreviousFallthrough->getLoc(),
1121-
diag::fallthrough_into_case_with_var_binding, expected->getName());
1122-
}
1123-
}
1124-
}
1132+
checkFallthroughPatternBindingsAndTypes(caseBlock, previousBlock);
11251133
}
11261134

11271135
// Type-check the body statements.

0 commit comments

Comments
 (0)