Skip to content

Commit 165fc40

Browse files
authored
Merge pull request #25272 from DougGregor/property-wrappers-default-init-crash-sr-10830
2 parents 2bc397b + 1a555df commit 165fc40

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

lib/AST/Decl.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5475,16 +5475,33 @@ bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
54755475
if (!ctx.getLazyResolver())
54765476
return false;
54775477

5478-
// If there is no initializer, the initialization form depends on
5479-
// whether the property wrapper type has an init(initialValue:).
5480-
if (!isParentInitialized()) {
5481-
auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo();
5482-
return wrapperTypeInfo.initialValueInit != nullptr;
5483-
}
5478+
auto customAttr = getAttachedPropertyWrapper();
5479+
if (!customAttr)
5480+
return false;
5481+
5482+
auto *PBD = getParentPatternBinding();
5483+
if (!PBD)
5484+
return false;
5485+
5486+
// If there was an initializer on the original property, initialize
5487+
// via the initial value.
5488+
if (PBD->getPatternList()[0].getEqualLoc().isValid())
5489+
return true;
5490+
5491+
// If there was an initializer on the attribute itself, initialize
5492+
// via the full wrapper.
5493+
if (customAttr->getArg() != nullptr)
5494+
return false;
54845495

5485-
// Otherwise, check whether the '=' initialization form was used.
5486-
return getPropertyWrapperBackingPropertyInfo().originalInitialValue
5487-
!= nullptr;
5496+
// If the property wrapper is default-initializable, it's the wrapper
5497+
// being initialized.
5498+
if (PBD->isDefaultInitializable(0))
5499+
return false;
5500+
5501+
// There is no initializer, so the initialization form depends on
5502+
// whether the property wrapper type has an init(initialValue:).
5503+
auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo();
5504+
return wrapperTypeInfo.initialValueInit != nullptr;
54885505
}
54895506

54905507
Identifier VarDecl::getObjCPropertyName() const {

test/IDE/print_property_wrappers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct HasWrappers {
4747
var z: String
4848

4949
// Memberwise initializer.
50-
// CHECK: init(x: Wrapper<Int> = Wrapper(closure: foo), y: Bool = true, z: String = Wrapper())
50+
// CHECK: init(x: Wrapper<Int> = Wrapper(closure: foo), y: Bool = true, z: Wrapper<String> = Wrapper())
5151
}
5252

5353
func trigger() {

test/SILGen/property_wrappers.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,34 @@ extension ClassUsingWrapper {
269269
}
270270
}
271271

272+
//
273+
@_propertyWrapper
274+
struct WrapperWithDefaultInit<T> {
275+
private var storage: T?
276+
277+
init() {
278+
self.storage = nil
279+
}
280+
281+
init(initialValue: T) {
282+
self.storage = initialValue
283+
}
284+
285+
var value: T {
286+
get { return storage! }
287+
set { storage = newValue }
288+
}
289+
}
290+
291+
class UseWrapperWithDefaultInit {
292+
@WrapperWithDefaultInit var name: String
293+
}
294+
295+
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s17property_wrappers25UseWrapperWithDefaultInitC5$name33_F728088E0028E14D18C6A10CF68512E8LLAA0defG0VySSGvpfi : $@convention(thin) () -> @owned WrapperWithDefaultInit<String>
296+
// CHECK: function_ref @$s17property_wrappers22WrapperWithDefaultInitVACyxGycfC
297+
// CHECK: return {{%.*}} : $WrapperWithDefaultInit<String>
298+
299+
272300
// CHECK-LABEL: sil_vtable ClassUsingWrapper {
273301
// CHECK: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter
274302
// CHECK: #ClassUsingWrapper.x!setter.1: (ClassUsingWrapper) -> (Int) -> () : @$s17property_wrappers17ClassUsingWrapperC1xSivs // ClassUsingWrapper.x.setter

0 commit comments

Comments
 (0)