@@ -1016,6 +1016,36 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10161016 });
10171017 }
10181018
1019+ void checkUnknownAttrRestrictions (CaseStmt *caseBlock,
1020+ bool &limitExhaustivityChecks) {
1021+ if (caseBlock->getCaseLabelItems ().size () != 1 ) {
1022+ assert (!caseBlock->getCaseLabelItems ().empty () &&
1023+ " parser should not produce case blocks with no items" );
1024+ TC.diagnose (caseBlock->getLoc (), diag::unknown_case_multiple_patterns)
1025+ .highlight (caseBlock->getCaseLabelItems ()[1 ].getSourceRange ());
1026+ limitExhaustivityChecks = true ;
1027+ }
1028+
1029+ if (FallthroughDest != nullptr ) {
1030+ if (!caseBlock->isDefault ())
1031+ TC.diagnose (caseBlock->getLoc (), diag::unknown_case_must_be_last);
1032+ limitExhaustivityChecks = true ;
1033+ }
1034+
1035+ const auto &labelItem = caseBlock->getCaseLabelItems ().front ();
1036+ if (labelItem.getGuardExpr () && !labelItem.isDefault ()) {
1037+ TC.diagnose (labelItem.getStartLoc (), diag::unknown_case_where_clause)
1038+ .highlight (labelItem.getGuardExpr ()->getSourceRange ());
1039+ }
1040+
1041+ const Pattern *pattern =
1042+ labelItem.getPattern ()->getSemanticsProvidingPattern ();
1043+ if (!isa<AnyPattern>(pattern)) {
1044+ TC.diagnose (labelItem.getStartLoc (), diag::unknown_case_must_be_catchall)
1045+ .highlight (pattern->getSourceRange ());
1046+ }
1047+ }
1048+
10191049 Stmt *visitSwitchStmt (SwitchStmt *switchStmt) {
10201050 // Type-check the subject expression.
10211051 Expr *subjectExpr = switchStmt->getSubjectExpr ();
@@ -1056,35 +1086,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10561086
10571087 // Check restrictions on '@unknown'.
10581088 if (caseBlock->hasUnknownAttr ()) {
1059- if (caseBlock->getCaseLabelItems ().size () != 1 ) {
1060- assert (!caseBlock->getCaseLabelItems ().empty () &&
1061- " parser should not produce case blocks with no items" );
1062- TC.diagnose (caseBlock->getLoc (),
1063- diag::unknown_case_multiple_patterns)
1064- .highlight (caseBlock->getCaseLabelItems ()[1 ].getSourceRange ());
1065- limitExhaustivityChecks = true ;
1066- }
1067-
1068- if (FallthroughDest != nullptr ) {
1069- if (!caseBlock->isDefault ())
1070- TC.diagnose (caseBlock->getLoc (), diag::unknown_case_must_be_last);
1071- limitExhaustivityChecks = true ;
1072- }
1073-
1074- const auto &labelItem = caseBlock->getCaseLabelItems ().front ();
1075- if (labelItem.getGuardExpr () && !labelItem.isDefault ()) {
1076- TC.diagnose (labelItem.getStartLoc (),
1077- diag::unknown_case_where_clause)
1078- .highlight (labelItem.getGuardExpr ()->getSourceRange ());
1079- }
1080-
1081- const Pattern *pattern =
1082- labelItem.getPattern ()->getSemanticsProvidingPattern ();
1083- if (!isa<AnyPattern>(pattern)) {
1084- TC.diagnose (labelItem.getStartLoc (),
1085- diag::unknown_case_must_be_catchall)
1086- .highlight (pattern->getSourceRange ());
1087- }
1089+ checkUnknownAttrRestrictions (caseBlock, limitExhaustivityChecks);
10881090 }
10891091
10901092 // If the previous case fellthrough, similarly check that that case's bindings
0 commit comments