Skip to content

Commit 8af4405

Browse files
committed
AST: 'lazy' property initializers are never @inlinable
In @Frozen structs, stored properties and property wrappers must have inlinable initial value expressions, since they are re-emitted into designated initializer bodies, which themselves might be @inlinable. However, 'lazy' properties don't follow this pattern; the initial value expression is emitted inside the getter, which is never @inlinable.
1 parent 587a8da commit 8af4405

File tree

3 files changed

+15
-10
lines changed

3 files changed

+15
-10
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,6 +1582,11 @@ VarDecl *PatternBindingDecl::getAnchoringVarDecl(unsigned i) const {
15821582
}
15831583

15841584
bool VarDecl::isInitExposedToClients() const {
1585+
// 'lazy' initializers are emitted inside the getter, which is never
1586+
// @inlinable.
1587+
if (getAttrs().hasAttribute<LazyAttr>())
1588+
return false;
1589+
15851590
return hasInitialValue() && isLayoutExposedToClients();
15861591
}
15871592

test/SPI/spi_members.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ public struct Resilient {
4747
@_spi(Foo) public lazy var lazyProperty2: Bar = Bar()
4848
// expected-error@-1 {{cannot use class 'Bar' here; it is SPI}}
4949
// 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}}
5250

5351
@_spi(Foo) @Wrapper public var wrappedProperty1: Bar
5452
// expected-error@-1 {{stored property 'wrappedProperty1' cannot be declared '@_spi' in a '@frozen' struct}}
@@ -73,12 +71,8 @@ public struct Resilient {
7371
public var computedProperty: Bar { Bar() } // expected-error {{cannot use class 'Bar' here; it is SPI}}
7472

7573
public lazy var lazyProperty1 = Bar() // expected-error {{cannot use class 'Bar' here; it is SPI}}
76-
// expected-error@-1 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
77-
// expected-error@-2 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
7874

7975
public lazy var lazyProperty2: Bar = Bar() // expected-error {{cannot use class 'Bar' here; it is SPI}}
80-
// expected-error@-1 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
81-
// expected-error@-2 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
8276

8377
@Wrapper public var wrappedProperty1: Bar
8478
// expected-error@-1 {{cannot use class 'Bar' here; it is SPI}}
@@ -105,12 +99,8 @@ public struct Resilient {
10599
private var computedProperty: Bar { Bar() }
106100

107101
private lazy var lazyProperty1 = Bar() // expected-error {{cannot use class 'Bar' here; it is SPI}}
108-
// expected-error@-1 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
109-
// expected-error@-2 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
110102

111103
private lazy var lazyProperty2: Bar = Bar() // expected-error {{cannot use class 'Bar' here; it is SPI}}
112-
// expected-error@-1 {{initializer 'init()' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
113-
// expected-error@-2 {{class 'Bar' cannot be used in a property initializer in a '@frozen' type because it is SPI}}
114104

115105
@Wrapper private var wrappedProperty1: Bar
116106
// expected-error@-1 {{cannot use class 'Bar' here; it is SPI}}

test/attr/attr_inlinable.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,13 @@ public struct PrivateInlinableCrash {
340340

341341
func innerFunction4(x: () = publicFunction()) {}
342342
}
343+
344+
// This is OK -- lazy property initializers are emitted inside the getter,
345+
// which is never @inlinable.
346+
@frozen public struct LazyField {
347+
public lazy var y: () = privateFunction()
348+
349+
@inlinable private lazy var z: () = privateFunction()
350+
// expected-error@-1 {{'@inlinable' attribute cannot be applied to stored properties}}
351+
}
352+

0 commit comments

Comments
 (0)