@@ -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