Skip to content

Commit f58d407

Browse files
committed
[Sema/SILGen] Consider init exprs associated with init accessor properties for memberwise init
1 parent fc895b4 commit f58d407

File tree

4 files changed

+77
-7
lines changed

4 files changed

+77
-7
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,13 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
14741474
if (auto pbd = dyn_cast<PatternBindingDecl>(member)) {
14751475
if (pbd->isStatic()) continue;
14761476

1477+
// Skip properties with init accessors, they could only be used
1478+
// explicitly and in memberwise initializers.
1479+
if (auto *var = pbd->getSingleVar()) {
1480+
if (var->hasInitAccessor())
1481+
continue;
1482+
}
1483+
14771484
for (auto i : range(pbd->getNumPatternEntries())) {
14781485
auto init = pbd->getExecutableInit(i);
14791486
if (!init) continue;

lib/Sema/CodeSynthesis.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,6 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
144144
if (!var->getParentPattern()->getSingleVar())
145145
return;
146146

147-
// FIXME: Don't attempt to synthesize default arguments for init
148-
// accessor properties because there could be multiple properties
149-
// with default values they are going to initialize.
150-
if (var->getAccessor(AccessorKind::Init))
151-
return;
152-
153147
// Whether we have explicit initialization.
154148
bool isExplicitlyInitialized = false;
155149
if (auto pbd = var->getParentPatternBinding()) {

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3359,7 +3359,7 @@ static void finishStorageImplInfo(AbstractStorageDecl *storage,
33593359
auto dc = storage->getDeclContext();
33603360

33613361
if (auto var = dyn_cast<VarDecl>(storage)) {
3362-
if (!info.hasStorage()) {
3362+
if (!info.hasStorage() && !var->hasInitAccessor()) {
33633363
if (auto *init = var->getParentExecutableInitializer()) {
33643364
auto &Diags = var->getASTContext().Diags;
33653365
Diags.diagnose(init->getLoc(), diag::getset_init)

test/Interpreter/init_accessors.swift

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,72 @@ test_memberwise_ordering()
393393
// CHECK: test-memberwise-ordering-1: Test1(_a: 0, _b: 42)
394394
// CHECK-NEXT: test-memberwise-ordering-2: Test2(_a: -1, _b: -2)
395395
// CHECK-NEXT: test-memberwise-ordering-3: Test3(_a: 1, _b: 2, _c: 3)
396+
397+
func test_memberwise_with_default_args() {
398+
struct TestWithoutDefault {
399+
var _a: Int
400+
var _b: Int
401+
402+
var pair: (Int, Int) = (-1, 42) {
403+
init(initialValue) initializes(_a, _b) {
404+
_a = initialValue.0
405+
_b = initialValue.1
406+
}
407+
408+
get { (0, 42) }
409+
set { }
410+
}
411+
}
412+
413+
let test1 = TestWithoutDefault()
414+
print("test-memberwise_with_default-1: \(test1)")
415+
416+
let test2 = TestWithoutDefault(pair: (42, -1))
417+
print("test-memberwise_with_default-2: \(test2)")
418+
419+
struct TestDefaulted {
420+
var _a: Int = 0
421+
var _b: Int = 0
422+
423+
var pair: (Int, Int) = (1, 2) {
424+
init(initialValue) initializes(_a, _b) {
425+
_a = initialValue.0
426+
_b = initialValue.1
427+
}
428+
429+
get { (_a, _b) }
430+
set { }
431+
}
432+
}
433+
434+
let test3 = TestDefaulted()
435+
print("test-defaulted-1: \(test3)")
436+
437+
let test4 = TestDefaulted(pair: (3, 4))
438+
print("test-defaulted-2: \(test4)")
439+
440+
class TestClass {
441+
var _q: String = "<<default>>"
442+
var _a: Int = 1
443+
444+
var pair: (String, Int) = ("", 42) {
445+
init(initialValue) initializes(_q, _a) {
446+
_q = initialValue.0
447+
_a = initialValue.1
448+
}
449+
450+
get { (_q, _a) }
451+
set { }
452+
}
453+
}
454+
455+
let test5 = TestClass()
456+
print("test-defaulted-class: \(test5.pair)")
457+
}
458+
459+
test_memberwise_with_default_args()
460+
// CHECK: test-memberwise_with_default-1: TestWithoutDefault(_a: -1, _b: 42)
461+
// CHECK-NEXT: test-memberwise_with_default-2: TestWithoutDefault(_a: 42, _b: -1)
462+
// CHECK-NEXT: test-defaulted-1: TestDefaulted(_a: 0, _b: 0)
463+
// CHECK-NEXT: test-defaulted-2: TestDefaulted(_a: 3, _b: 4)
464+
// CHECK-NEXT: test-defaulted-class: ("<<default>>", 1)

0 commit comments

Comments
 (0)