Skip to content

Commit 1a555df

Browse files
committed
[SE-0258] Fix memberwise initializer involving wrapped properties.
The determination of which type to use within the implicit memberwise initializer for a wrapper property (between the original property type and the wrapper type) could be affected by the synthesis of the call to the default initializer. Rewrite the logic here to depend on aspects of the AST that don't change with further type checking.
1 parent a82d33f commit 1a555df

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

lib/AST/Decl.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5475,21 +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-
// If it's default-initializable, that doesn't use an initial value.
5482-
if (auto *PBD = getParentPatternBinding())
5483-
if (PBD->isDefaultInitializable())
5484-
return false;
5478+
auto customAttr = getAttachedPropertyWrapper();
5479+
if (!customAttr)
5480+
return false;
54855481

5486-
auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo();
5487-
return wrapperTypeInfo.initialValueInit != nullptr;
5488-
}
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;
54895495

5490-
// Otherwise, check whether the '=' initialization form was used.
5491-
return getPropertyWrapperBackingPropertyInfo().originalInitialValue
5492-
!= 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;
54935505
}
54945506

54955507
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() {

0 commit comments

Comments
 (0)