Skip to content

Commit 763bcf9

Browse files
committed
[SILGen] Don't use assign_by_wrapper for local property wrappers if
there is an initial wrapped value.
1 parent af71c5d commit 763bcf9

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,12 @@ namespace {
13191319
if (!(isAssignmentToSelfParamInInit || VD->getDeclContext()->isLocalContext()))
13201320
return false;
13211321

1322+
// If this var isn't in a type context, assignment will always use the setter
1323+
// if there is an initial value.
1324+
if (!VD->getDeclContext()->isTypeContext() &&
1325+
wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue())
1326+
return false;
1327+
13221328
// If we have a nonmutating setter on a value type, the call
13231329
// captures all of 'self' and we cannot rewrite an assignment
13241330
// into an initialization.

test/SILGen/property_wrapper_local.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ func testLocalWrapper() {
5151
// CHECK-LABEL: sil private [ossa] @$s22property_wrapper_local16testLocalWrapperyyF5valueL_Sivs : $@convention(thin) (Int, @guaranteed { var Wrapper<Int> }) -> () {
5252
}
5353

54+
func testInitialValue() {
55+
// CHECK-LABEL: sil hidden [ossa] @$s22property_wrapper_local16testInitialValueyyF : $@convention(thin) () -> () {
56+
57+
@Wrapper var value: Int = 10
58+
// CHECK: function_ref @$s22property_wrapper_local16testInitialValueyyF5valueL_SivpfP : $@convention(thin) (Int) -> Wrapper<Int>
59+
60+
value = 15
61+
// CHECK: function_ref @$s22property_wrapper_local16testInitialValueyyF5valueL_Sivs : $@convention(thin) (Int, @guaranteed { var Wrapper<Int> }) -> ()
62+
// CHECK-NOT: assign_by_wrapper
63+
// CHECK: return
64+
65+
// CHECK-LABEL: sil private [ossa] @$s22property_wrapper_local16testInitialValueyyF5valueL_SivpfP : $@convention(thin) (Int) -> Wrapper<Int> {
66+
}
67+
5468
@propertyWrapper
5569
enum Lazy<Value> {
5670
case uninitialized(() -> Value)

test/SILOptimizer/di_property_wrappers_errors.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,23 @@ struct UseWrapperWithAutoclosure {
9999
} // expected-error{{return from initializer without initializing all stored properties}}
100100
// expected-note@-1{{'self.wrapped' not initialized}}
101101
}
102+
103+
@propertyWrapper
104+
struct Wrapper<T> {
105+
var wrappedValue: T
106+
}
107+
108+
func local() {
109+
var anotherVar: String // expected-note {{variable defined here}}
110+
111+
@Wrapper var value = 10 {
112+
didSet {
113+
anotherVar = "hello!"
114+
}
115+
}
116+
117+
value = 15 // expected-error {{variable 'anotherVar' used by function definition before being initialized}}
118+
119+
anotherVar = "hello!"
120+
_ = anotherVar
121+
}

0 commit comments

Comments
 (0)