Skip to content

Commit c9d084d

Browse files
committed
Sema: Diagnose @_spi on elements of @frozen enums.
rdar://72873771
1 parent a01d427 commit c9d084d

File tree

4 files changed

+39
-33
lines changed

4 files changed

+39
-33
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,9 @@ ERROR(spi_attribute_on_protocol_requirement,none,
19701970
ERROR(spi_attribute_on_frozen_stored_properties,none,
19711971
"stored property %0 cannot be declared '@_spi' in a '@frozen' struct",
19721972
(DeclName))
1973+
ERROR(spi_attribute_on_frozen_enum_case,none,
1974+
"%0 %1 cannot be declared '@_spi' in a '@frozen' enum",
1975+
(DescriptiveDeclKind, DeclName))
19731976
WARNING(spi_attribute_on_import_of_public_module,none,
19741977
"'@_spi' import of %0 will not include any SPI symbols; "
19751978
"%0 was built from the public interface at %1",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,17 @@ void AttributeChecker::visitSPIAccessControlAttr(SPIAccessControlAttr *attr) {
11501150
}
11511151
}
11521152
}
1153+
1154+
// Forbid enum elements marked SPI in frozen types.
1155+
if (auto elt = dyn_cast<EnumElementDecl>(VD)) {
1156+
if (auto ED = dyn_cast<EnumDecl>(D->getDeclContext())) {
1157+
if (ED->getAttrs().hasAttribute<FrozenAttr>(/*allowInvalid*/ true) &&
1158+
!ED->isSPI()) {
1159+
diagnoseAndRemoveAttr(attr, diag::spi_attribute_on_frozen_enum_case,
1160+
VD->getDescriptiveKind(), VD->getName());
1161+
}
1162+
}
1163+
}
11531164
}
11541165

11551166
if (auto ID = dyn_cast<ImportDecl>(D)) {

test/SPI/resilience.swift

Lines changed: 0 additions & 29 deletions
This file was deleted.

test/SPI/spi_members.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class Bar {
1414
public init() {}
1515
}
1616

17-
public struct Resilient {
17+
public struct ResilientStructSPIMembers {
1818
public init() {}
1919

2020
@_spi(Foo) public func method(_: Bar) {}
@@ -28,7 +28,7 @@ public struct Resilient {
2828
@_spi(Foo) @Wrapper public var wrappedProperty2 = Bar()
2929
}
3030

31-
@frozen public struct Good {
31+
@frozen public struct FrozenStructSPIMembers {
3232
public init() {}
3333

3434
@_spi(Foo) public func method(_: Bar) {}
@@ -55,7 +55,7 @@ public struct Resilient {
5555
// expected-error@-1 {{stored property 'wrappedProperty2' cannot be declared '@_spi' in a '@frozen' struct}}
5656
}
5757

58-
@frozen public struct Bad {
58+
@frozen public struct FrozenStructPublicMembers {
5959
public init() {}
6060

6161
public func method(_: Bar) {} // expected-error {{cannot use class 'Bar' here; it is SPI}}
@@ -83,7 +83,7 @@ public struct Resilient {
8383
// expected-error@-3 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
8484
}
8585

86-
@frozen public struct BadPrivate {
86+
@frozen public struct FrozenStructPrivateMembers {
8787
private init() {}
8888

8989
private func method(_: Bar) {}
@@ -110,3 +110,24 @@ public struct Resilient {
110110
// expected-error@-2 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
111111
// expected-error@-3 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
112112
}
113+
114+
public enum ResilientEnum {
115+
@_spi(S)
116+
case okSpiCase
117+
118+
@_spi(S)
119+
case okSpiCaseWithPayload(_: Int)
120+
}
121+
122+
@frozen
123+
public enum FrozenEnum {
124+
case okCase
125+
126+
@_spi(S) // expected-error {{enum case 'spiCase' cannot be declared '@_spi' in a '@frozen' enum}}
127+
case spiCase
128+
129+
case okCaseWithPayload(_: Int)
130+
131+
@_spi(S) // expected-error {{enum case 'spiCaseWithPayload' cannot be declared '@_spi' in a '@frozen' enum}}
132+
case spiCaseWithPayload(_: Int)
133+
}

0 commit comments

Comments
 (0)