Skip to content

Commit f228f73

Browse files
authored
Merge pull request #38011 from xedin/rdar-79523605
[CSSimplify] Fix warning check to account that "from" might be less optional than "to" type
2 parents 21084b4 + c1bac12 commit f228f73

File tree

4 files changed

+15
-10
lines changed

4 files changed

+15
-10
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7466,8 +7466,8 @@ SourceRange CheckedCastBaseFailure::getCastRange() const {
74667466
llvm_unreachable("There is no other kind of checked cast!");
74677467
}
74687468

7469-
std::tuple<Type, Type, unsigned>
7470-
CoercibleOptionalCheckedCastFailure::unwrapedTypes() const {
7469+
std::tuple<Type, Type, int>
7470+
CoercibleOptionalCheckedCastFailure::unwrappedTypes() const {
74717471
SmallVector<Type, 4> fromOptionals;
74727472
SmallVector<Type, 4> toOptionals;
74737473
Type unwrappedFromType =
@@ -7483,8 +7483,7 @@ bool CoercibleOptionalCheckedCastFailure::diagnoseIfExpr() const {
74837483
return false;
74847484

74857485
Type unwrappedFrom, unwrappedTo;
7486-
unsigned extraFromOptionals;
7487-
std::tie(unwrappedFrom, unwrappedTo, extraFromOptionals) = unwrapedTypes();
7486+
std::tie(unwrappedFrom, unwrappedTo, std::ignore) = unwrappedTypes();
74887487

74897488
SourceRange diagFromRange = getFromRange();
74907489
SourceRange diagToRange = getToRange();
@@ -7515,8 +7514,8 @@ bool CoercibleOptionalCheckedCastFailure::diagnoseForcedCastExpr() const {
75157514
auto fromType = getFromType();
75167515
auto toType = getToType();
75177516
Type unwrappedFrom, unwrappedTo;
7518-
unsigned extraFromOptionals;
7519-
std::tie(unwrappedFrom, unwrappedTo, extraFromOptionals) = unwrapedTypes();
7517+
int extraFromOptionals;
7518+
std::tie(unwrappedFrom, unwrappedTo, extraFromOptionals) = unwrappedTypes();
75207519

75217520
SourceRange diagFromRange = getFromRange();
75227521
SourceRange diagToRange = getToRange();
@@ -7558,8 +7557,7 @@ bool CoercibleOptionalCheckedCastFailure::diagnoseConditionalCastExpr() const {
75587557
auto fromType = getFromType();
75597558
auto toType = getToType();
75607559
Type unwrappedFrom, unwrappedTo;
7561-
unsigned extraFromOptionals;
7562-
std::tie(unwrappedFrom, unwrappedTo, extraFromOptionals) = unwrapedTypes();
7560+
std::tie(unwrappedFrom, unwrappedTo, std::ignore) = unwrappedTypes();
75637561

75647562
SourceRange diagFromRange = getFromRange();
75657563
SourceRange diagToRange = getToRange();

lib/Sema/CSDiagnostics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2496,7 +2496,7 @@ class CoercibleOptionalCheckedCastFailure final
24962496
bool diagnoseAsError() override;
24972497

24982498
private:
2499-
std::tuple<Type, Type, unsigned> unwrapedTypes() const;
2499+
std::tuple<Type, Type, int> unwrappedTypes() const;
25002500

25012501
bool diagnoseIfExpr() const;
25022502

lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6549,7 +6549,9 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
65496549
if (!castExpr)
65506550
return nullptr;
65516551

6552-
unsigned extraOptionals = fromOptionals.size() - toOptionals.size();
6552+
// "from" could be less optional than "to" e.g. `0 as Any?`, so
6553+
// we need to store the difference as a signed integer.
6554+
int extraOptionals = fromOptionals.size() - toOptionals.size();
65536555
// Removing the optionality from to type when the force cast expr is an IUO.
65546556
const auto *const TR = castExpr->getCastTypeRepr();
65556557
if (isExpr<ForcedCheckedCastExpr>(anchor) && TR &&
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-swift-frontend %s -typecheck -verify
2+
3+
func test() -> Any? {
4+
0 as! Any? // expected-warning {{forced cast from 'Int' to 'Any?' always succeeds; did you mean to use 'as'?}}
5+
}

0 commit comments

Comments
 (0)