@@ -947,6 +947,75 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
947947 return S;
948948 }
949949
950+ void checkCaseLabelItem (CaseStmt *caseBlock, CaseLabelItem &labelItem,
951+ bool &limitExhaustivityChecks, Type subjectType) {
952+ SWIFT_DEFER {
953+ // Check the guard expression, if present.
954+ if (auto *guard = labelItem.getGuardExpr ()) {
955+ limitExhaustivityChecks |= TC.typeCheckCondition (guard, DC);
956+ labelItem.setGuardExpr (guard);
957+ }
958+ };
959+
960+ Pattern *pattern = labelItem.getPattern ();
961+ auto *newPattern = TC.resolvePattern (pattern, DC,
962+ /* isStmtCondition*/ false );
963+ if (!newPattern)
964+ return ;
965+ pattern = newPattern;
966+ // Coerce the pattern to the subject's type.
967+ TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
968+ if (!subjectType ||
969+ TC.coercePatternToType (pattern, TypeResolution::forContextual (DC),
970+ subjectType, patternOptions)) {
971+ limitExhaustivityChecks = true ;
972+
973+ // If that failed, mark any variables binding pieces of the pattern
974+ // as invalid to silence follow-on errors.
975+ pattern->forEachVariable ([&](VarDecl *VD) { VD->markInvalid (); });
976+ }
977+ labelItem.setPattern (pattern);
978+
979+ // For each variable in the pattern, make sure its type is identical to what
980+ // it was in the first label item's pattern.
981+ auto *firstPattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
982+ SmallVector<VarDecl *, 4 > vars;
983+ firstPattern->collectVariables (vars);
984+ pattern->forEachVariable ([&](VarDecl *vd) {
985+ if (!vd->hasName ())
986+ return ;
987+ for (auto *expected : vars) {
988+ if (expected->hasName () && expected->getName () == vd->getName ()) {
989+ if (vd->hasType () && expected->hasType () && !expected->isInvalid () &&
990+ !vd->getType ()->isEqual (expected->getType ())) {
991+ TC.diagnose (vd->getLoc (), diag::type_mismatch_multiple_pattern_list,
992+ vd->getType (), expected->getType ());
993+ vd->markInvalid ();
994+ expected->markInvalid ();
995+ }
996+ if (expected->isLet () != vd->isLet ()) {
997+ auto diag = TC.diagnose (
998+ vd->getLoc (), diag::mutability_mismatch_multiple_pattern_list,
999+ vd->isLet (), expected->isLet ());
1000+
1001+ VarPattern *foundVP = nullptr ;
1002+ vd->getParentPattern ()->forEachNode ([&](Pattern *P) {
1003+ if (auto *VP = dyn_cast<VarPattern>(P))
1004+ if (VP->getSingleVar () == vd)
1005+ foundVP = VP;
1006+ });
1007+ if (foundVP)
1008+ diag.fixItReplace (foundVP->getLoc (),
1009+ expected->isLet () ? " let" : " var" );
1010+ vd->markInvalid ();
1011+ expected->markInvalid ();
1012+ }
1013+ return ;
1014+ }
1015+ }
1016+ });
1017+ }
1018+
9501019 Stmt *visitSwitchStmt (SwitchStmt *switchStmt) {
9511020 // Type-check the subject expression.
9521021 Expr *subjectExpr = switchStmt->getSubjectExpr ();
@@ -979,73 +1048,10 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
9791048 FallthroughDest = std::next (i) == e ? nullptr : *std::next (i);
9801049
9811050 for (auto &labelItem : caseBlock->getMutableCaseLabelItems ()) {
982- // Resolve the pattern in the label.
983- Pattern *pattern = labelItem.getPattern ();
984- if (auto *newPattern = TC.resolvePattern (pattern, DC,
985- /* isStmtCondition*/ false )) {
986- pattern = newPattern;
987- // Coerce the pattern to the subject's type.
988- TypeResolutionOptions patternOptions (TypeResolverContext::InExpression);
989- if (!subjectType ||
990- TC.coercePatternToType (pattern, TypeResolution::forContextual (DC),
991- subjectType, patternOptions)) {
992- limitExhaustivityChecks = true ;
993-
994- // If that failed, mark any variables binding pieces of the pattern
995- // as invalid to silence follow-on errors.
996- pattern->forEachVariable ([&](VarDecl *VD) {
997- VD->markInvalid ();
998- });
999- }
1000- labelItem.setPattern (pattern);
1001-
1002- // For each variable in the pattern, make sure its type is identical to what it
1003- // was in the first label item's pattern.
1004- auto *firstPattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
1005- SmallVector<VarDecl *, 4 > vars;
1006- firstPattern->collectVariables (vars);
1007- pattern->forEachVariable ([&](VarDecl *vd) {
1008- if (!vd->hasName ())
1009- return ;
1010- for (auto *expected : vars) {
1011- if (expected->hasName () && expected->getName () == vd->getName ()) {
1012- if (vd->hasType () && expected->hasType () &&
1013- !expected->isInvalid () &&
1014- !vd->getType ()->isEqual (expected->getType ())) {
1015- TC.diagnose (vd->getLoc (),
1016- diag::type_mismatch_multiple_pattern_list,
1017- vd->getType (), expected->getType ());
1018- vd->markInvalid ();
1019- expected->markInvalid ();
1020- }
1021- if (expected->isLet () != vd->isLet ()) {
1022- auto diag = TC.diagnose (
1023- vd->getLoc (),
1024- diag::mutability_mismatch_multiple_pattern_list,
1025- vd->isLet (), expected->isLet ());
1026-
1027- VarPattern *foundVP = nullptr ;
1028- vd->getParentPattern ()->forEachNode ([&](Pattern *P) {
1029- if (auto *VP = dyn_cast<VarPattern>(P))
1030- if (VP->getSingleVar () == vd)
1031- foundVP = VP;
1032- });
1033- if (foundVP)
1034- diag.fixItReplace (foundVP->getLoc (),
1035- expected->isLet () ? " let" : " var" );
1036- vd->markInvalid ();
1037- expected->markInvalid ();
1038- }
1039- return ;
1040- }
1041- }
1042- });
1043- }
1044- // Check the guard expression, if present.
1045- if (auto *guard = labelItem.getGuardExpr ()) {
1046- limitExhaustivityChecks |= TC.typeCheckCondition (guard, DC);
1047- labelItem.setGuardExpr (guard);
1048- }
1051+ // Resolve the pattern in our case label if it has not been resolved
1052+ // and check that our var decls follow invariants.
1053+ checkCaseLabelItem (caseBlock, labelItem, limitExhaustivityChecks,
1054+ subjectType);
10491055 }
10501056
10511057 // Check restrictions on '@unknown'.
0 commit comments