Skip to content

Commit b4c568e

Browse files
committed
Sema: Use VarDecl::isLayoutExposedToClients() when checking if @_spi attribute is allowed
We need to prohibit 'lazy' properties and property wrappers from being declared @_spi inside of a @Frozen struct. Making them SPI doesn't make sense, because these properties will be omitted from the module interface and not taken into account when clients manipulate values of this type.
1 parent 0dffe5c commit b4c568e

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -967,14 +967,15 @@ void AttributeChecker::visitSPIAccessControlAttr(SPIAccessControlAttr *attr) {
967967
}
968968

969969
// Forbid stored properties marked SPI in frozen types.
970-
if (auto property = dyn_cast<AbstractStorageDecl>(VD))
971-
if (auto DC = dyn_cast<NominalTypeDecl>(D->getDeclContext()))
972-
if (property->hasStorage() &&
973-
!DC->isFormallyResilient() &&
974-
!DC->isSPI())
970+
if (auto property = dyn_cast<VarDecl>(VD)) {
971+
if (auto NTD = dyn_cast<NominalTypeDecl>(D->getDeclContext())) {
972+
if (property->isLayoutExposedToClients() && !NTD->isSPI()) {
975973
diagnoseAndRemoveAttr(attr,
976974
diag::spi_attribute_on_frozen_stored_properties,
977975
VD->getName());
976+
}
977+
}
978+
}
978979
}
979980
}
980981

test/SPI/spi_members.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public struct Wrapper<T> {
99

1010
@_spi(Foo)
1111
public class Bar {
12-
// expected-note@-1 11{{type declared here}}
12+
// expected-note@-1 12{{type declared here}}
1313

1414
public init() {}
1515
}
@@ -42,9 +42,19 @@ public struct Resilient {
4242
// expected-error@-1 {{stored property 'storedProperty2' cannot be declared '@_spi' in a '@frozen' struct}}
4343

4444
@_spi(Foo) public lazy var lazyProperty1 = Bar()
45+
// expected-error@-1 {{stored property 'lazyProperty1' cannot be declared '@_spi' in a '@frozen' struct}}
46+
4547
@_spi(Foo) public lazy var lazyProperty2: Bar = Bar()
48+
// expected-error@-1 {{cannot use class 'Bar' here; it is SPI}}
49+
// expected-error@-2 {{stored property 'lazyProperty2' cannot be declared '@_spi' in a '@frozen' struct}}
50+
// expected-error@-3 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
51+
// expected-error@-4 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
52+
4653
@_spi(Foo) @Wrapper public var wrappedProperty1: Bar
54+
// expected-error@-1 {{stored property 'wrappedProperty1' cannot be declared '@_spi' in a '@frozen' struct}}
55+
4756
@_spi(Foo) @Wrapper public var wrappedProperty2 = Bar()
57+
// expected-error@-1 {{stored property 'wrappedProperty2' cannot be declared '@_spi' in a '@frozen' struct}}
4858
}
4959

5060
@frozen public struct Bad {

0 commit comments

Comments
 (0)