Skip to content

Commit d813579

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.
1 parent ed9e01c commit d813579

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
@@ -2341,11 +2341,11 @@ WARNING(optional_pattern_match_promotion,none,
23412341
WARNING(optional_to_any_coercion,none,
23422342
"expression implicitly coerced from %0 to Any", (Type))
23432343
NOTE(default_optional_to_any,none,
2344-
"provide a default value to avoid the warning", ())
2344+
"provide a default value to avoid this warning", ())
23452345
NOTE(force_optional_to_any,none,
2346-
"force-unwrap the value to avoid the warning", ())
2346+
"force-unwrap the value to avoid this warning", ())
23472347
NOTE(silence_optional_to_any,none,
2348-
"explicitly cast to Any with 'as Any' to silence the warning", ())
2348+
"explicitly cast to Any with 'as Any' to silence this warning", ())
23492349

23502350
ERROR(invalid_noescape_use,none,
23512351
"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
@@ -3593,7 +3593,7 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
35933593

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

35993599
class OptionalToAnyCoercionWalker : public ASTWalker {
@@ -3605,13 +3605,12 @@ static void diagnoseOptionalToAnyCoercion(TypeChecker &TC, const Expr *E,
36053605
return { false, E };
36063606

36073607
if (auto *coercion = dyn_cast<CoerceExpr>(E)) {
3608-
if (E->getType()->getDesugaredType()->isAny() &&
3609-
isa<ErasureExpr>(coercion->getSubExpr()))
3608+
if (E->getType()->isAny() && isa<ErasureExpr>(coercion->getSubExpr()))
36103609
ErasureCoercedToAny.insert(coercion->getSubExpr());
36113610
} else if (isa<ErasureExpr>(E) && !ErasureCoercedToAny.count(E) &&
3612-
E->getType()->getDesugaredType()->isAny()) {
3611+
E->getType()->isAny()) {
36133612
auto subExpr = cast<ErasureExpr>(E)->getSubExpr();
3614-
auto erasedTy = subExpr->getType()->getDesugaredType();
3613+
auto erasedTy = subExpr->getType();
36153614
if (erasedTy->getOptionalObjectType()) {
36163615
TC.diagnose(subExpr->getStartLoc(), diag::optional_to_any_coercion,
36173616
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)