@@ -742,6 +742,25 @@ ContinueTargetRequest::evaluate(Evaluator &evaluator,
742742 CS->getTargetName (), CS->getTargetLoc (), /* isContinue*/ true , DC);
743743}
744744
745+ FallthroughSourceAndDest
746+ FallthroughSourceAndDestRequest::evaluate (Evaluator &evaluator,
747+ const FallthroughStmt *FS) const {
748+ auto *SF = FS->getDeclContext ()->getParentSourceFile ();
749+ auto &ctx = SF->getASTContext ();
750+ auto loc = FS->getLoc ();
751+
752+ auto [src, dest] = ASTScope::lookupFallthroughSourceAndDest (SF, loc);
753+ if (!src) {
754+ ctx.Diags .diagnose (loc, diag::fallthrough_outside_switch);
755+ return {};
756+ }
757+ if (!dest) {
758+ ctx.Diags .diagnose (loc, diag::fallthrough_from_last_case);
759+ return {};
760+ }
761+ return {src, dest};
762+ }
763+
745764static Expr *getDeclRefProvidingExpressionForHasSymbol (Expr *E) {
746765 // Strip coercions, which are necessary in source to disambiguate overloaded
747766 // functions or generic functions, e.g.
@@ -925,12 +944,18 @@ static bool typeCheckConditionForStatement(LabeledConditionalStmt *stmt,
925944 return false ;
926945}
927946
928- // / Verify that the pattern bindings for the cases that we're falling through
929- // / from and to are equivalent.
930- static void checkFallthroughPatternBindingsAndTypes (
931- ASTContext &ctx,
932- CaseStmt *caseBlock, CaseStmt *previousBlock,
933- FallthroughStmt *fallthrough) {
947+ // / Check the correctness of a 'fallthrough' statement.
948+ // /
949+ // / \returns true if an error occurred.
950+ bool swift::checkFallthroughStmt (FallthroughStmt *FS) {
951+ auto &ctx = FS->getDeclContext ()->getASTContext ();
952+ auto *caseBlock = FS->getFallthroughDest ();
953+ auto *previousBlock = FS->getFallthroughSource ();
954+ if (!previousBlock || !caseBlock)
955+ return true ;
956+
957+ // Verify that the pattern bindings for the cases that we're falling through
958+ // from and to are equivalent.
934959 auto firstPattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
935960 SmallVector<VarDecl *, 4 > vars;
936961 firstPattern->collectVariables (vars);
@@ -969,36 +994,10 @@ static void checkFallthroughPatternBindingsAndTypes(
969994
970995 if (!matched) {
971996 ctx.Diags .diagnose (
972- fallthrough ->getLoc (), diag::fallthrough_into_case_with_var_binding,
997+ FS ->getLoc (), diag::fallthrough_into_case_with_var_binding,
973998 expected->getName ());
974999 }
9751000 }
976- }
977-
978- // / Check the correctness of a 'fallthrough' statement.
979- // /
980- // / \returns true if an error occurred.
981- bool swift::checkFallthroughStmt (DeclContext *dc, FallthroughStmt *stmt) {
982- CaseStmt *fallthroughSource;
983- CaseStmt *fallthroughDest;
984- ASTContext &ctx = dc->getASTContext ();
985- auto sourceFile = dc->getParentSourceFile ();
986- std::tie (fallthroughSource, fallthroughDest) =
987- ASTScope::lookupFallthroughSourceAndDest (sourceFile, stmt->getLoc ());
988-
989- if (!fallthroughSource) {
990- ctx.Diags .diagnose (stmt->getLoc (), diag::fallthrough_outside_switch);
991- return true ;
992- }
993- if (!fallthroughDest) {
994- ctx.Diags .diagnose (stmt->getLoc (), diag::fallthrough_from_last_case);
995- return true ;
996- }
997- stmt->setFallthroughSource (fallthroughSource);
998- stmt->setFallthroughDest (fallthroughDest);
999-
1000- checkFallthroughPatternBindingsAndTypes (
1001- ctx, fallthroughDest, fallthroughSource, stmt);
10021001 return false ;
10031002}
10041003
@@ -1457,7 +1456,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
14571456 }
14581457
14591458 Stmt *visitFallthroughStmt (FallthroughStmt *S) {
1460- if (checkFallthroughStmt (DC, S))
1459+ if (checkFallthroughStmt (S))
14611460 return nullptr ;
14621461
14631462 return S;
0 commit comments