@@ -742,6 +742,25 @@ ContinueTargetRequest::evaluate(Evaluator &evaluator,
742
742
CS->getTargetName (), CS->getTargetLoc (), /* isContinue*/ true , DC);
743
743
}
744
744
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
+
745
764
static Expr *getDeclRefProvidingExpressionForHasSymbol (Expr *E) {
746
765
// Strip coercions, which are necessary in source to disambiguate overloaded
747
766
// functions or generic functions, e.g.
@@ -925,12 +944,18 @@ static bool typeCheckConditionForStatement(LabeledConditionalStmt *stmt,
925
944
return false ;
926
945
}
927
946
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.
934
959
auto firstPattern = caseBlock->getCaseLabelItems ()[0 ].getPattern ();
935
960
SmallVector<VarDecl *, 4 > vars;
936
961
firstPattern->collectVariables (vars);
@@ -969,36 +994,10 @@ static void checkFallthroughPatternBindingsAndTypes(
969
994
970
995
if (!matched) {
971
996
ctx.Diags .diagnose (
972
- fallthrough ->getLoc (), diag::fallthrough_into_case_with_var_binding,
997
+ FS ->getLoc (), diag::fallthrough_into_case_with_var_binding,
973
998
expected->getName ());
974
999
}
975
1000
}
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);
1002
1001
return false ;
1003
1002
}
1004
1003
@@ -1457,7 +1456,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1457
1456
}
1458
1457
1459
1458
Stmt *visitFallthroughStmt (FallthroughStmt *S) {
1460
- if (checkFallthroughStmt (DC, S))
1459
+ if (checkFallthroughStmt (S))
1461
1460
return nullptr ;
1462
1461
1463
1462
return S;
0 commit comments