Skip to content

Commit e46d6fd

Browse files
authored
Merge pull request #30590 from DougGregor/property-wrapper-backing-init-linkage
[Property wrappers] Fix property wrapper backing initializer linkage.
2 parents a1c4b68 + a15a905 commit e46d6fd

File tree

5 files changed

+36
-13
lines changed

5 files changed

+36
-13
lines changed

lib/SIL/SILDeclRef.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,8 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
293293
limit = Limit::NeverPublic;
294294
}
295295

296-
// The property wrapper backing initializer is never public for resilient
297-
// properties.
298-
if (kind == SILDeclRef::Kind::PropertyWrapperBackingInitializer) {
299-
if (cast<VarDecl>(d)->isResilient())
300-
limit = Limit::NeverPublic;
301-
}
302-
303296
// Stored property initializers get the linkage of their containing type.
304-
if (isStoredPropertyInitializer()) {
297+
if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer()) {
305298
// Three cases:
306299
//
307300
// 1) Type is formally @_fixed_layout/@frozen. Root initializers can be
@@ -483,7 +476,7 @@ IsSerialized_t SILDeclRef::isSerialized() const {
483476

484477
// Stored property initializers are inlinable if the type is explicitly
485478
// marked as @frozen.
486-
if (isStoredPropertyInitializer()) {
479+
if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer()) {
487480
auto *nominal = cast<NominalTypeDecl>(d->getDeclContext());
488481
auto scope =
489482
nominal->getFormalAccessScope(/*useDC=*/nullptr,
@@ -1118,8 +1111,7 @@ bool SILDeclRef::canBeDynamicReplacement() const {
11181111
bool SILDeclRef::isDynamicallyReplaceable() const {
11191112
if (kind == SILDeclRef::Kind::DefaultArgGenerator)
11201113
return false;
1121-
if (isStoredPropertyInitializer() ||
1122-
kind == SILDeclRef::Kind::PropertyWrapperBackingInitializer)
1114+
if (isStoredPropertyInitializer() || isPropertyWrapperBackingInitializer())
11231115
return false;
11241116

11251117
// Class allocators are not dynamic replaceable.

test/SILGen/dynamically_replaceable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ struct WrapperWithInitialValue<T> {
414414
}
415415
}
416416

417-
// CHECK-LABEL: sil hidden [ossa] @$s23dynamically_replaceable10SomeStructV1tSbvpfP
417+
// CHECK-NOT: sil hidden [ossa] @$s23dynamically_replaceable10SomeStructV1tSbvpfP
418418
public struct SomeStruct {
419419
@WrapperWithInitialValue var t = false
420420
}

test/SILGen/property_wrappers.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,8 @@ public protocol TestProtocol {}
510510
public class TestClass<T> {
511511
@WrapperWithInitialValue var value: T
512512

513+
// CHECK-LABEL: sil [ossa] @$s17property_wrappers9TestClassC5valuexvpfP : $@convention(thin) <T> (@in T) -> @out WrapperWithInitialValue<T>
514+
513515
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers9TestClassC5value8protocolACyxGx_qd__tcAA0C8ProtocolRd__lufc
514516
// CHECK: [[BACKING_INIT:%.*]] = function_ref @$s17property_wrappers9TestClassC5valuexvpfP : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @out WrapperWithInitialValue<τ_0_0>
515517
// CHECK-NEXT: partial_apply [callee_guaranteed] [[BACKING_INIT]]<T>()
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend -emit-module -o %t -enable-library-evolution %S/Inputs/property_wrapper_defs.swift
3-
// RUN: %target-swift-emit-silgen -primary-file %s -I %t -enable-library-evolution
3+
// RUN: %target-swift-emit-silgen -primary-file %s -I %t -enable-library-evolution | %FileCheck %s
44
import property_wrapper_defs
55

66
// rdar://problem/55995892
77
// This is a crash that occurs only with -enable-library-evolution.
88

99
public enum E { case a }
1010
struct M { @MyPublished private var e = E.a }
11+
12+
// Ensure that the backing initializer is serialized.
13+
@frozen
14+
public struct StructUsesPublishedAsPrivate {
15+
public var integer: Int = 17
16+
17+
// CHECK: sil non_abi [serialized] [ossa] @$s35property_wrappers_library_evolution28StructUsesPublishedAsPrivateV6stringSSvpfP : $@convention(thin) (@owned String) -> @out MyPublished<String>
18+
@MyPublished var string: String = "Hello"
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-swift-frontend -typecheck %s -verify -enable-library-evolution
2+
3+
@propertyWrapper
4+
public struct ResilientWrapper<T> {
5+
public var wrappedValue: T
6+
7+
public init(wrappedValue: T, description: String) {
8+
self.wrappedValue = wrappedValue
9+
}
10+
}
11+
12+
func getHello() -> String { return "hello" } // expected-note 2 {{global function 'getHello()' is not '@usableFromInline' or public}}
13+
14+
@frozen
15+
public struct StructUsesPublishedAsPrivate {
16+
public var integer: Int = 17
17+
18+
@ResilientWrapper(description: getHello()) // expected-error 2 {{global function 'getHello()' is internal and cannot be referenced from a property initializer in a '@frozen' type}}
19+
var otherString: String = "World"
20+
}

0 commit comments

Comments
 (0)