Skip to content

Commit 8628b94

Browse files
committed
Improvements to optional-to-Any coercion warning.
Don't explicitly desguar types when it is not needed and/or results in worse types displayed in diagnostics. Tweak the warning messages to use "this warning" rather than "the warning". Addresses feedback from Jordan on commit 401ca24. (cherry picked from commit d813579)
1 parent 981a782 commit 8628b94

File tree

3 files changed

+41
-49
lines changed

3 files changed

+41
-49
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,11 +2331,11 @@ WARNING(optional_pattern_match_promotion,none,
23312331
WARNING(optional_to_any_coercion,none,
23322332
"expression implicitly coerced from %0 to Any", (Type))
23332333
NOTE(default_optional_to_any,none,
2334-
"provide a default value to avoid the warning", ())
2334+
"provide a default value to avoid this warning", ())
23352335
NOTE(force_optional_to_any,none,
2336-
"force-unwrap the value to avoid the warning", ())
2336+
"force-unwrap the value to avoid this warning", ())
23372337
NOTE(silence_optional_to_any,none,
2338-
"explicitly cast to Any with 'as Any' to silence the warning", ())
2338+
"explicitly cast to Any with 'as Any' to silence this warning", ())
23392339

23402340
ERROR(invalid_noescape_use,none,
23412341
"non-escaping %select{value|parameter}1 %0 may only be called",

lib/Sema/MiscDiagnostics.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,7 +3596,7 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
35963596

35973597
static void diagnoseOptionalToAnyCoercion(TypeChecker &TC, const Expr *E,
35983598
const DeclContext *DC) {
3599-
if (E == nullptr || isa<ErrorExpr>(E) || !E->getType())
3599+
if (!E || isa<ErrorExpr>(E) || !E->getType())
36003600
return;
36013601

36023602
class OptionalToAnyCoercionWalker : public ASTWalker {
@@ -3608,13 +3608,12 @@ static void diagnoseOptionalToAnyCoercion(TypeChecker &TC, const Expr *E,
36083608
return { false, E };
36093609

36103610
if (auto *coercion = dyn_cast<CoerceExpr>(E)) {
3611-
if (E->getType()->getDesugaredType()->isAny() &&
3612-
isa<ErasureExpr>(coercion->getSubExpr()))
3611+
if (E->getType()->isAny() && isa<ErasureExpr>(coercion->getSubExpr()))
36133612
ErasureCoercedToAny.insert(coercion->getSubExpr());
36143613
} else if (isa<ErasureExpr>(E) && !ErasureCoercedToAny.count(E) &&
3615-
E->getType()->getDesugaredType()->isAny()) {
3614+
E->getType()->isAny()) {
36163615
auto subExpr = cast<ErasureExpr>(E)->getSubExpr();
3617-
auto erasedTy = subExpr->getType()->getDesugaredType();
3616+
auto erasedTy = subExpr->getType();
36183617
if (erasedTy->getOptionalObjectType()) {
36193618
TC.diagnose(subExpr->getStartLoc(), diag::optional_to_any_coercion,
36203619
erasedTy)

test/Sema/diag_optional_to_any.swift

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,61 +7,54 @@ func takeAny(_ left: Any, _ right: Any) -> Int? {
77
func throwing() throws -> Int? {}
88

99
func warnOptionalToAnyCoercion(value x: Int?) -> Any {
10-
let a: Any = x // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
11-
// expected-note@-1 {{provide a default value to avoid the warning}}
12-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
13-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
10+
let a: Any = x // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
11+
// expected-note@-1 {{provide a default value to avoid this warning}}
12+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
13+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
1414

1515
let b: Any = x as Any
1616

17-
let c: Any = takeAny(a, b) // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
18-
// expected-note@-1 {{provide a default value to avoid the warning}}
19-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
20-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
17+
let c: Any = takeAny(a, b) // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
18+
// expected-note@-1 {{provide a default value to avoid this warning}}
19+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
20+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
2121

22-
let d: Any = takeAny(c, c) as Any
22+
let _: Any = takeAny(c, c) as Any
2323

24-
let e: Any = (x) // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
25-
// expected-note@-1 {{provide a default value to avoid the warning}}
26-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
27-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
28-
29-
_ = takeAny(d, e)
24+
let _: Any = (x) // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
25+
// expected-note@-1 {{provide a default value to avoid this warning}}
26+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
27+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
3028

3129
let f: Any = (x as Any)
3230
let g: Any = (x) as (Any)
3331

34-
_ = takeAny(f as? Int, g) // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
35-
// expected-note@-1 {{provide a default value to avoid the warning}}
36-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
37-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
38-
39-
let h: Any = takeAny(f as? Int, g) as Any // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
40-
// expected-note@-1 {{provide a default value to avoid the warning}}
41-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
42-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
32+
_ = takeAny(f as? Int, g) // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
33+
// expected-note@-1 {{provide a default value to avoid this warning}}
34+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
35+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
4336

44-
let i: Any = takeAny(f as? Int as Any, g) as Any
37+
let _: Any = takeAny(f as? Int, g) as Any // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
38+
// expected-note@-1 {{provide a default value to avoid this warning}}
39+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
40+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
4541

46-
_ = takeAny(h, i)
42+
let _: Any = takeAny(f as? Int as Any, g) as Any
4743

48-
let j: Any = x! == x! ? 1 : x // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
49-
// expected-note@-1 {{provide a default value to avoid the warning}}
50-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
51-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
44+
let _: Any = x! == x! ? 1 : x // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
45+
// expected-note@-1 {{provide a default value to avoid this warning}}
46+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
47+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
5248

53-
let k: Any
5449
do {
55-
k = try throwing() // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
56-
// expected-note@-1 {{provide a default value to avoid the warning}}
57-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
58-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
50+
let _: Any = try throwing() // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
51+
// expected-note@-1 {{provide a default value to avoid this warning}}
52+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
53+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
5954
} catch {}
6055

61-
_ = takeAny(j, k)
62-
63-
return x // expected-warning {{expression implicitly coerced from 'Optional<Int>' to Any}}
64-
// expected-note@-1 {{provide a default value to avoid the warning}}
65-
// expected-note@-2 {{force-unwrap the value to avoid the warning}}
66-
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence}}
56+
return x // expected-warning {{expression implicitly coerced from 'Int?' to Any}}
57+
// expected-note@-1 {{provide a default value to avoid this warning}}
58+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}
59+
// expected-note@-3 {{explicitly cast to Any with 'as Any' to silence this warning}}
6760
}

0 commit comments

Comments
 (0)