Skip to content

Commit 5f00a1b

Browse files
committed
[SILGen] In a memberwise initializer, apply the property wrapper backing
initializer for property wrappers that are not memberwise initialized but have an explicit original wrapped value.
1 parent c130848 commit 5f00a1b

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,21 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
220220

221221
// Cleanup after this initialization.
222222
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
223+
224+
// If this is a property wrapper backing storage var that isn't
225+
// memberwise initialized and has an original wrapped value, apply
226+
// the property wrapper backing initializer.
227+
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
228+
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
229+
if (wrappedInfo.originalInitialValue) {
230+
auto arg = SGF.emitRValue(wrappedInfo.originalInitialValue);
231+
maybeEmitPropertyWrapperInitFromValue(SGF, Loc, field, subs,
232+
std::move(arg))
233+
.forwardInto(SGF, Loc, init.get());
234+
continue;
235+
}
236+
}
237+
223238
SGF.emitExprInto(field->getParentInitializer(), init.get());
224239
}
225240
}
@@ -235,27 +250,38 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
235250
for (VarDecl *field : decl->getStoredProperties()) {
236251
auto fieldTy =
237252
selfTy.getFieldType(field, SGF.SGM.M, SGF.getTypeExpansionContext());
238-
SILValue v;
253+
RValue value;
239254

240255
// If it's memberwise initialized, do so now.
241256
if (field->isMemberwiseInitialized(/*preferDeclaredProperties=*/false)) {
242257
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
243258
assert(elti != eltEnd && "number of args does not match number of fields");
244259
(void)eltEnd;
245-
v = maybeEmitPropertyWrapperInitFromValue(
246-
SGF, Loc, field, subs, std::move(*elti))
247-
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);
260+
value = std::move(*elti);
248261
++elti;
249262
} else {
250263
// Otherwise, use its initializer.
251264
assert(field->isParentInitialized());
265+
Expr *init = field->getParentInitializer();
266+
267+
// If this is a property wrapper backing storage var that isn't
268+
// memberwise initialized, use the original wrapped value if it exists.
269+
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
270+
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
271+
if (wrappedInfo.originalInitialValue) {
272+
init = wrappedInfo.originalInitialValue;
273+
}
274+
}
252275

253-
// Cleanup after this initialization.
254-
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
255-
v = SGF.emitRValue(field->getParentInitializer())
256-
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);
276+
value = SGF.emitRValue(init);
257277
}
258278

279+
// Cleanup after this initialization.
280+
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
281+
SILValue v = maybeEmitPropertyWrapperInitFromValue(SGF, Loc, field, subs,
282+
std::move(value))
283+
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);
284+
259285
eltValues.push_back(v);
260286
}
261287

test/SILGen/property_wrappers.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ struct HasMemberwiseInit<T: DefaultInit> {
3232

3333
@WrapperWithInitialValue(wrappedValue: 17)
3434
var z: Int
35+
36+
@WrapperWithInitialValue
37+
private var p: Bool = true
3538
}
3639

3740
func forceHasMemberwiseInit() {
@@ -76,6 +79,11 @@ func forceHasMemberwiseInit() {
7679
// CHECK-NOT: return
7780
// CHECK: function_ref @$s17property_wrappers23WrapperWithInitialValueV07wrappedF0ACyxGx_tcfC : $@convention(method) <τ_0_0> (@in τ_0_0, @thin WrapperWithInitialValue<τ_0_0>.Type) -> @out WrapperWithInitialValue<τ_0_0>
7881

82+
// variable initialization expression of HasMemberwiseInit._p
83+
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s17property_wrappers17HasMemberwiseInitV2_p33_{{.*}}23WrapperWithInitialValueVySbGvpfi : $@convention(thin) <T where T : DefaultInit> () -> Bool {
84+
// CHECK: function_ref @$sSb22_builtinBooleanLiteralSbBi1__tcfC : $@convention(method) (Builtin.Int1, @thin Bool.Type) -> Bool
85+
// CHECK: return {{%.*}} : $Bool
86+
7987
// default argument 0 of HasMemberwiseInit.init(x:y:z:)
8088
// CHECK: sil hidden [ossa] @$s17property_wrappers17HasMemberwiseInitV1x1y1zACyxGAA7WrapperVySbG_xAA0F16WithInitialValueVySiGtcfcfA_ : $@convention(thin) <T where T : DefaultInit> () -> Wrapper<Bool>
8189

@@ -103,8 +111,33 @@ func forceHasMemberwiseInit() {
103111
// CHECK-NOT: return
104112
// CHECK: function_ref @$s17property_wrappers17HasMemberwiseInitV2_z33_{{.*}}23WrapperWithInitialValueVySiGvpfi : $@convention(thin) <τ_0_0 where τ_0_0 : DefaultInit> () -> WrapperWithInitialValue<Int>
105113

114+
// Initialization of p
115+
// CHECK-NOT: return
116+
// CHECK: function_ref @$s17property_wrappers17HasMemberwiseInitV2_p33_{{.*}}23WrapperWithInitialValueVySbGvpfi : $@convention(thin) <τ_0_0 where τ_0_0 : DefaultInit> () -> Bool
117+
// CHECK-NOT: return
118+
// CHECK: function_ref @$s17property_wrappers17HasMemberwiseInitV1p33_{{.*}} : $@convention(thin) <τ_0_0 where τ_0_0 : DefaultInit> (Bool) -> WrapperWithInitialValue<Bool>
119+
106120
// CHECK: return
107121

122+
// Non-generic struct with private property wrapper
123+
struct HasMemberwiseInitWithPrivateWrapper {
124+
@WrapperWithInitialValue
125+
var z: Int = 17
126+
127+
@WrapperWithInitialValue
128+
private var p: Bool = true
129+
130+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers35HasMemberwiseInitWithPrivateWrapperV1zACSi_tcfC : $@convention(method) (Int, @thin HasMemberwiseInitWithPrivateWrapper.Type) -> HasMemberwiseInitWithPrivateWrapper {
131+
// CHECK: function_ref @$s17property_wrappers35HasMemberwiseInitWithPrivateWrapperV1zSivpfP : $@convention(thin) (Int) -> WrapperWithInitialValue<Int>
132+
// CHECK: function_ref @$s17property_wrappers35HasMemberwiseInitWithPrivateWrapperV1p33_{{.*}} : $@convention(thin) (Bool) -> WrapperWithInitialValue<Bool>
133+
// CHECK: return {{%.*}} : $HasMemberwiseInitWithPrivateWrapper
134+
}
135+
136+
func forceHasMemberwiseInitWithPrivateWrapper() {
137+
_ = HasMemberwiseInitWithPrivateWrapper(z: 42)
138+
}
139+
140+
108141
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s17property_wrappers9HasNestedV2_y33_{{.*}}14PrivateWrapperAELLVyx_SayxGGvpfi : $@convention(thin) <T> () -> @owned Array<T> {
109142
// CHECK: bb0:
110143
// CHECK: function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF

0 commit comments

Comments
 (0)