Skip to content

Commit f745115

Browse files
committed
Improved Cast Diagnostics when Literals are involved
Fixes Issue #53822
1 parent 8ac71b1 commit f745115

File tree

3 files changed

+9
-7
lines changed

3 files changed

+9
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,9 +1184,9 @@ WARNING(conditional_downcast_coercion,none,
11841184
(Type, Type))
11851185

11861186
WARNING(literal_conditional_downcast_to_coercion,none,
1187-
"conditional downcast from literal to %0 always fails; "
1187+
"conditional downcast from literal of inferred type %0 to unrelated type %1 always fails; "
11881188
"consider using 'as' coercion",
1189-
(Type))
1189+
(Type, Type))
11901190

11911191
WARNING(forced_downcast_noop,none,
11921192
"forced cast of %0 to same type has no effect", (Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8621,6 +8621,7 @@ bool UnsupportedRuntimeCheckedCastFailure::diagnoseAsError() {
86218621
}
86228622

86238623
bool CheckedCastToUnrelatedFailure::diagnoseAsError() {
8624+
const auto fromType = getFromType();
86248625
const auto toType = getToType();
86258626
auto *sub = CastExpr->getSubExpr()->getSemanticsProvidingExpr();
86268627
// FIXME(https://github.com/apple/swift/issues/54529): This literal diagnostics needs to be revisited by a proposal to unify casting semantics for literals.
@@ -8632,7 +8633,8 @@ bool CheckedCastToUnrelatedFailure::diagnoseAsError() {
86328633
// be statically coerced to the cast type.
86338634
if (protocol && TypeChecker::conformsToProtocol(toType, protocol,
86348635
dc->getParentModule())) {
8635-
emitDiagnostic(diag::literal_conditional_downcast_to_coercion, toType);
8636+
emitDiagnostic(diag::literal_conditional_downcast_to_coercion, fromType,
8637+
toType);
86368638
return true;
86378639
}
86388640
}

test/expr/cast/literals_downcast.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
let ok = "A" as Character // OK
44
let succeed = "A" as? String // expected-warning {{always succeeds}}
5-
let bad = "A" as? Character // expected-warning {{conditional downcast from literal to 'Character' always fails; consider using 'as' coercion}} {{none}}
5+
let bad = "A" as? Character // expected-warning {{conditional downcast from literal of inferred type 'String' to unrelated type 'Character' always fails; consider using 'as' coercion}} {{none}}
66
let bad2 = "Aa" as? Character // expected-warning {{cast from 'String' to unrelated type 'Character' always fails}}
77
let bad1 = 1 as? Character // expected-warning {{cast from 'Int' to unrelated type 'Character' always fails}}
88

99
let okInt = 1 as Int // OK
1010
let badInt = 1 as? Int // expected-warning {{always succeeds}}
1111
let badInt1 = 1.0 as? Int // expected-warning {{cast from 'Double' to unrelated type 'Int' always fails}}
12-
let badInt2 = 1 as? Double // expected-warning {{conditional downcast from literal to 'Double' always fails; consider using 'as' coercion}} {{none}}
12+
let badInt2 = 1 as? Double // expected-warning {{conditional downcast from literal of inferred type 'Int' to unrelated type 'Double' always fails; consider using 'as' coercion}} {{none}}
1313

1414
let okUInt = 1 as UInt // OK
15-
let badUInt = 1 as? UInt // expected-warning {{conditional downcast from literal to 'UInt' always fails; consider using 'as' coercion}} {{none}}
15+
let badUInt = 1 as? UInt // expected-warning {{conditional downcast from literal of inferred type 'Int' to unrelated type 'UInt' always fails; consider using 'as' coercion}} {{none}}
1616
let badUInt1 = 1.0 as? UInt // expected-warning {{cast from 'Double' to unrelated type 'UInt' always fails}}
1717

1818
// Custom protocol adoption
@@ -21,4 +21,4 @@ struct S: ExpressibleByStringLiteral {
2121
init(stringLiteral value: Self.StringLiteralType) {}
2222
}
2323

24-
let a = "A" as? S // expected-warning {{conditional downcast from literal to 'S' always fails; consider using 'as' coercion}} {{none}}
24+
let a = "A" as? S // expected-warning {{conditional downcast from literal of inferred type 'String' to unrelated type 'S' always fails; consider using 'as' coercion}} {{none}}

0 commit comments

Comments
 (0)