@@ -4419,61 +4419,57 @@ void swift::performAbstractFuncDeclDiagnostics(AbstractFunctionDecl *AFD) {
4419
4419
}
4420
4420
}
4421
4421
4422
- // Perform MiscDiagnostics on Switch Statements.
4423
- static void checkSwitch (ASTContext &ctx, const SwitchStmt *stmt,
4424
- DeclContext *DC) {
4425
- // We want to warn about "case .Foo, .Bar where 1 != 100:" since the where
4426
- // clause only applies to the second case, and this is surprising.
4427
- for (auto cs : stmt->getCases ()) {
4428
- TypeChecker::checkExistentialTypes (ctx, cs, DC);
4429
-
4430
- // The case statement can have multiple case items, each can have a where.
4431
- // If we find a "where", and there is a preceding item without a where, and
4432
- // if they are on the same source line, then warn.
4433
- auto items = cs->getCaseLabelItems ();
4434
-
4435
- // Don't do any work for the vastly most common case.
4436
- if (items.size () == 1 ) continue ;
4437
-
4438
- // Ignore the first item, since it can't have preceding ones.
4439
- for (unsigned i = 1 , e = items.size (); i != e; ++i) {
4440
- // Must have a where clause.
4441
- auto where = items[i].getGuardExpr ();
4442
- if (!where)
4443
- continue ;
4444
-
4445
- // Preceding item must not.
4446
- if (items[i-1 ].getGuardExpr ())
4447
- continue ;
4448
-
4449
- // Must be on the same source line.
4450
- auto prevLoc = items[i-1 ].getStartLoc ();
4451
- auto thisLoc = items[i].getStartLoc ();
4452
- if (prevLoc.isInvalid () || thisLoc.isInvalid ())
4453
- continue ;
4454
-
4455
- auto &SM = ctx.SourceMgr ;
4456
- auto prevLineCol = SM.getLineAndColumnInBuffer (prevLoc);
4457
- if (SM.getLineAndColumnInBuffer (thisLoc).first != prevLineCol.first )
4458
- continue ;
4422
+ static void diagnoseCaseStmtAmbiguousWhereClause (const CaseStmt *CS,
4423
+ ASTContext &ctx) {
4424
+ // The case statement can have multiple case items, each can have a where.
4425
+ // If we find a "where", and there is a preceding item without a where, and
4426
+ // if they are on the same source line, e.g
4427
+ // "case .Foo, .Bar where 1 != 100:" then warn since it may be unexpected.
4428
+ auto items = CS->getCaseLabelItems ();
4429
+
4430
+ // Don't do any work for the vastly most common case.
4431
+ if (items.size () == 1 )
4432
+ return ;
4459
4433
4460
- ctx.Diags .diagnose (items[i].getWhereLoc (), diag::where_on_one_item)
4434
+ // Ignore the first item, since it can't have preceding ones.
4435
+ for (unsigned i = 1 , e = items.size (); i != e; ++i) {
4436
+ // Must have a where clause.
4437
+ auto where = items[i].getGuardExpr ();
4438
+ if (!where)
4439
+ continue ;
4440
+
4441
+ // Preceding item must not.
4442
+ if (items[i - 1 ].getGuardExpr ())
4443
+ continue ;
4444
+
4445
+ // Must be on the same source line.
4446
+ auto prevLoc = items[i - 1 ].getStartLoc ();
4447
+ auto thisLoc = items[i].getStartLoc ();
4448
+ if (prevLoc.isInvalid () || thisLoc.isInvalid ())
4449
+ continue ;
4450
+
4451
+ auto &SM = ctx.SourceMgr ;
4452
+ auto prevLineCol = SM.getLineAndColumnInBuffer (prevLoc);
4453
+ if (SM.getLineAndColumnInBuffer (thisLoc).first != prevLineCol.first )
4454
+ continue ;
4455
+
4456
+ ctx.Diags
4457
+ .diagnose (items[i].getWhereLoc (), diag::where_on_one_item,
4458
+ CS->getParentKind () == CaseParentKind::DoCatch)
4461
4459
.highlight (items[i].getPattern ()->getSourceRange ())
4462
4460
.highlight (where->getSourceRange ());
4463
-
4464
- // Whitespace it out to the same column as the previous item.
4465
- std::string whitespace (prevLineCol.second -1 , ' ' );
4466
- ctx.Diags .diagnose (thisLoc, diag::add_where_newline)
4467
- .fixItInsert (thisLoc, " \n " +whitespace);
4468
-
4469
- auto whereRange = SourceRange (items[i].getWhereLoc (),
4470
- where->getEndLoc ());
4471
- auto charRange = Lexer::getCharSourceRangeFromSourceRange (SM, whereRange);
4472
- auto whereText = SM.extractText (charRange);
4473
- ctx.Diags .diagnose (prevLoc, diag::duplicate_where)
4474
- .fixItInsertAfter (items[i-1 ].getEndLoc (), " " + whereText.str ())
4475
- .highlight (items[i-1 ].getSourceRange ());
4476
- }
4461
+
4462
+ // Whitespace it out to the same column as the previous item.
4463
+ std::string whitespace (prevLineCol.second - 1 , ' ' );
4464
+ ctx.Diags .diagnose (thisLoc, diag::add_where_newline)
4465
+ .fixItInsert (thisLoc, " \n " + whitespace);
4466
+
4467
+ auto whereRange = SourceRange (items[i].getWhereLoc (), where->getEndLoc ());
4468
+ auto charRange = Lexer::getCharSourceRangeFromSourceRange (SM, whereRange);
4469
+ auto whereText = SM.extractText (charRange);
4470
+ ctx.Diags .diagnose (prevLoc, diag::duplicate_where)
4471
+ .fixItInsertAfter (items[i - 1 ].getEndLoc (), " " + whereText.str ())
4472
+ .highlight (items[i - 1 ].getSourceRange ());
4477
4473
}
4478
4474
}
4479
4475
@@ -6194,8 +6190,8 @@ void swift::performStmtDiagnostics(const Stmt *S, DeclContext *DC) {
6194
6190
6195
6191
TypeChecker::checkExistentialTypes (ctx, const_cast <Stmt *>(S), DC);
6196
6192
6197
- if (auto switchStmt = dyn_cast<SwitchStmt >(S))
6198
- checkSwitch (ctx, switchStmt, DC );
6193
+ if (auto *CS = dyn_cast<CaseStmt >(S))
6194
+ diagnoseCaseStmtAmbiguousWhereClause (CS, ctx );
6199
6195
6200
6196
checkStmtConditionTrailingClosure (ctx, S);
6201
6197
0 commit comments