Skip to content

Commit 511ada4

Browse files
committed
Sema: Ban potential unavailability on enum cases with associated values
This cannot be supported for the same reasons struct and class stored properties with potential unavailability cannot be supported. It is possible that some users relied on this, because it worked in some cases where the type metadata for the potentially unavailable type was not actually needed for anything (eg, if the type was @Frozen and trivial, or a simple class reference). If this becomes an issue we can downgrade this to a warning. Note that just like the previous fix for stored properties, we do still allow writing an '@available' attribute on the enum element if the OS version is not any newer than the deployment target. This allows annotating APIs with the OS version where they were introduced.
1 parent cb9c1f9 commit 511ada4

File tree

4 files changed

+43
-9
lines changed

4 files changed

+43
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5178,6 +5178,10 @@ ERROR(availability_stored_property_no_potential,
51785178
none, "stored properties cannot be marked potentially unavailable with "
51795179
"'@available'", ())
51805180

5181+
ERROR(availability_enum_element_no_potential,
5182+
none, "enum cases with associated values cannot be marked potentially unavailable with "
5183+
"'@available'", ())
5184+
51815185
ERROR(availability_protocol_requires_version,
51825186
none, "protocol %0 requires %1 to be available in %2 %3 and newer",
51835187
(Identifier, DeclName, StringRef, llvm::VersionTuple))

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,6 +3418,12 @@ TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
34183418
// for potential unavailability.
34193419
if (!VD->isStatic() && !VD->getDeclContext()->isModuleScopeContext())
34203420
return diag::availability_stored_property_no_potential;
3421+
3422+
} else if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
3423+
// An enum element with an associated value cannot be potentially
3424+
// unavailable.
3425+
if (EED->hasAssociatedValues())
3426+
return diag::availability_enum_element_no_potential;
34213427
}
34223428

34233429
return None;

test/Sema/availability_stored.swift

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,52 @@
99
struct NewStruct {}
1010

1111
@available(macOS 50, *)
12-
struct GoodReference {
12+
struct GoodReferenceStruct {
1313
var x: NewStruct
1414
}
1515

1616
@available(macOS 50, *)
17-
struct GoodNestedReference {
17+
struct GoodNestedReferenceStruct {
1818
struct Inner {
1919
var x: NewStruct
2020
}
2121
}
2222

23-
struct BadReference1 {
23+
struct BadReferenceStruct1 {
2424
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
2525
@available(macOS 50, *)
2626
var x: NewStruct
2727
}
2828

2929
@available(macOS 40, *)
30-
struct BadReference2 {
30+
struct BadReferenceStruct2 {
3131
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
3232
@available(macOS 50, *)
3333
var x: NewStruct
3434
}
35+
36+
// The same behavior should hold for enum elements with payloads.
37+
@available(macOS 50, *)
38+
enum GoodReferenceEnum {
39+
case x(NewStruct)
40+
}
41+
42+
@available(macOS 50, *)
43+
enum GoodNestedReferenceEnum {
44+
enum Inner {
45+
case x(NewStruct)
46+
}
47+
}
48+
49+
enum BadReferenceEnum1 {
50+
// expected-error@+1 {{enum cases with associated values cannot be marked potentially unavailable with '@available'}}
51+
@available(macOS 50, *)
52+
case x(NewStruct)
53+
}
54+
55+
@available(macOS 40, *)
56+
enum BadReferenceEnum2 {
57+
// expected-error@+1 {{enum cases with associated values cannot be marked potentially unavailable with '@available'}}
58+
@available(macOS 50, *)
59+
case x(NewStruct)
60+
}

test/Sema/availability_versions.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -537,17 +537,17 @@ enum CompassPoint {
537537

538538
case WithAvailableByEnumPayload(p : EnumIntroducedOn10_51)
539539

540+
// expected-error@+1 {{enum cases with associated values cannot be marked potentially unavailable with '@available'}}
540541
@available(OSX, introduced: 10.52)
541542
case WithAvailableByEnumElementPayload(p : EnumIntroducedOn10_52)
542543

544+
// expected-error@+1 2{{enum cases with associated values cannot be marked potentially unavailable with '@available'}}
543545
@available(OSX, introduced: 10.52)
544546
case WithAvailableByEnumElementPayload1(p : EnumIntroducedOn10_52), WithAvailableByEnumElementPayload2(p : EnumIntroducedOn10_52)
545547

546548
case WithUnavailablePayload(p : EnumIntroducedOn10_52) // expected-error {{'EnumIntroducedOn10_52' is only available in macOS 10.52 or newer}}
547-
// expected-note@-1 {{add @available attribute to enclosing case}}
548549

549-
case WithUnavailablePayload1(p : EnumIntroducedOn10_52), WithUnavailablePayload2(p : EnumIntroducedOn10_52) // expected-error 2{{'EnumIntroducedOn10_52' is only available in macOS 10.52 or newer}}
550-
// expected-note@-1 2{{add @available attribute to enclosing case}}
550+
case WithUnavailablePayload1(p : EnumIntroducedOn10_52), WithUnavailablePayload2(p : EnumIntroducedOn10_52) // expected-error 2{{'EnumIntroducedOn10_52' is only available in macOS 10.52 or newer}}
551551
}
552552

553553
@available(OSX, introduced: 10.52)
@@ -1336,11 +1336,9 @@ enum EnumForFixit {
13361336
// expected-note@-1 2{{add @available attribute to enclosing enum}} {{1-1=@available(macOS 10.51, *)\n}}
13371337
case CaseWithUnavailablePayload(p: ClassAvailableOn10_51)
13381338
// expected-error@-1 {{'ClassAvailableOn10_51' is only available in macOS 10.51 or newer}}
1339-
// expected-note@-2 {{add @available attribute to enclosing case}} {{3-3=@available(macOS 10.51, *)\n }}
13401339

13411340
case CaseWithUnavailablePayload2(p: ClassAvailableOn10_51), WithoutPayload
13421341
// expected-error@-1 {{'ClassAvailableOn10_51' is only available in macOS 10.51 or newer}}
1343-
// expected-note@-2 {{add @available attribute to enclosing case}} {{3-3=@available(macOS 10.51, *)\n }}
13441342

13451343
}
13461344

0 commit comments

Comments
 (0)