Skip to content

Commit 08f80ec

Browse files
committed
Properly handle subscripts when avoiding IUO-to-Any coercion warnings.
Ensure that we grab the decl from the subscript expression so that we can check whether it returns an IUO. Also add tests for subscripts and failable inits.
1 parent dbb5bc4 commit 08f80ec

File tree

4 files changed

+42
-12
lines changed

4 files changed

+42
-12
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3728,6 +3728,13 @@ static void diagnoseUnintendedOptionalBehavior(TypeChecker &TC, const Expr *E,
37283728
if (auto *call = dyn_cast<CallExpr>(E))
37293729
E = call->getDirectCallee();
37303730

3731+
if (auto *subscript = dyn_cast<SubscriptExpr>(E)) {
3732+
if (subscript->hasDecl())
3733+
return subscript->getDecl().getDecl();
3734+
3735+
return nullptr;
3736+
}
3737+
37313738
if (auto *memberRef = dyn_cast<MemberRefExpr>(E))
37323739
return memberRef->getMember().getDecl();
37333740
if (auto *declRef = dyn_cast<DeclRefExpr>(E))

test/ClangImporter/objc_parse.swift

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,27 +247,18 @@ func almostSubscriptableValueMismatch(_ as1: AlmostSubscriptable, a: A) {
247247
func almostSubscriptableKeyMismatch(_ bc: BadCollection, key: NSString) {
248248
// FIXME: We end up importing this as read-only due to the mismatch between
249249
// getter/setter element types.
250-
var _ : Any = bc[key] // expected-warning {{expression implicitly coerced from 'Any?' to 'Any'}}
251-
// expected-note@-1 {{force-unwrap the value to avoid this warning}}
252-
// expected-note@-2 {{provide a default value to avoid this warning}}
253-
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}
250+
var _ : Any = bc[key]
254251
}
255252

256253
func almostSubscriptableKeyMismatchInherited(_ bc: BadCollectionChild,
257254
key: String) {
258-
var value : Any = bc[key] // expected-warning {{expression implicitly coerced from 'Any?' to 'Any'}}
259-
// expected-note@-1 {{force-unwrap the value to avoid this warning}}
260-
// expected-note@-2 {{provide a default value to avoid this warning}}
261-
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}
255+
var value : Any = bc[key]
262256
bc[key] = value // expected-error{{cannot assign through subscript: subscript is get-only}}
263257
}
264258

265259
func almostSubscriptableKeyMismatchInherited(_ roc: ReadOnlyCollectionChild,
266260
key: String) {
267-
var value : Any = roc[key] // expected-warning {{expression implicitly coerced from 'Any?' to 'Any'}}
268-
// expected-note@-1 {{force-unwrap the value to avoid this warning}}
269-
// expected-note@-2 {{provide a default value to avoid this warning}}
270-
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}
261+
var value : Any = roc[key]
271262
roc[key] = value // expected-error{{cannot assign through subscript: subscript is get-only}}
272263
}
273264

test/Sema/diag_unintended_optional_behavior.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ class C {
8787
var b: Any?!
8888
func returningIUO() -> Int! { return a }
8989
func returningAny() -> Any { return a }
90+
91+
subscript(i: Int) -> Int! { return 0 }
92+
subscript(i: Float) -> Any! { return 0 }
93+
}
94+
95+
class D {
96+
init!() {}
9097
}
9198

9299
func returningIUO() -> Int! { return 1 }
@@ -96,6 +103,8 @@ func nowarnIUOToAnyCoercion(_ a: Int!, _ b: Any?!) {
96103
_ = takeAny(a, b)
97104
_ = takeAny(returningIUO(), C().returningIUO())
98105
_ = takeAny(C().a, C().b)
106+
_ = takeAny(C()[0], C()[1.0])
107+
_ = takeAny(D(), D())
99108

100109
_ = takeAny(a as Any, b as Any)
101110
}

test/Sema/diag_unintended_optional_behavior_swift_5.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ class C {
1616
// expected-note@-1 {{provide a default value to avoid this warning}}{{40-40= ?? <#default value#>}}
1717
// expected-note@-2 {{force-unwrap the value to avoid this warning}}{{40-40=!}}
1818
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{40-40= as Any}}
19+
20+
subscript(i: Int) -> Int! { return 0 }
21+
subscript(i: Float) -> Any! { return 0 }
22+
}
23+
24+
class D {
25+
init!() {}
1926
}
2027

2128
func returningIUO() -> Int! { return 1 }
@@ -43,6 +50,22 @@ func warnIUOToAnyCoercion(_ a: Int!, _ b: Any?!) {
4350
// expected-warning@-4 {{expression implicitly coerced from 'Any??' to 'Any'}}
4451
// expected-note@-5 {{force-unwrap the value to avoid this warning}}{{27-27=!!}}
4552
// expected-note@-6 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{27-27= as Any}}
53+
_ = takeAny(C()[0], C()[1.0]) // expected-warning {{expression implicitly coerced from 'Int?' to 'Any'}}
54+
// expected-note@-1 {{provide a default value to avoid this warning}}{{21-21= ?? <#default value#>}}
55+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}{{21-21=!}}
56+
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{21-21= as Any}}
57+
// expected-warning@-4 {{expression implicitly coerced from 'Any?' to 'Any'}}
58+
// expected-note@-5 {{provide a default value to avoid this warning}}{{31-31= ?? <#default value#>}}
59+
// expected-note@-6 {{force-unwrap the value to avoid this warning}}{{31-31=!}}
60+
// expected-note@-7 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{31-31= as Any}}
61+
_ = takeAny(D(), D()) // expected-warning {{expression implicitly coerced from 'D?' to 'Any'}}
62+
// expected-note@-1 {{provide a default value to avoid this warning}}{{18-18= ?? <#default value#>}}
63+
// expected-note@-2 {{force-unwrap the value to avoid this warning}}{{18-18=!}}
64+
// expected-note@-3 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{18-18= as Any}}
65+
// expected-warning@-4 {{expression implicitly coerced from 'D?' to 'Any'}}
66+
// expected-note@-5 {{provide a default value to avoid this warning}}{{23-23= ?? <#default value#>}}
67+
// expected-note@-6 {{force-unwrap the value to avoid this warning}}{{23-23=!}}
68+
// expected-note@-7 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}{{23-23= as Any}}
4669

4770
_ = takeAny(a as Any, b as Any)
4871
}

0 commit comments

Comments
 (0)