@@ -272,12 +272,13 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
272
272
subs, std::move (arg));
273
273
}
274
274
275
- static void emitApplyOfInitAccessor (SILGenFunction &SGF, SILLocation loc,
276
- AccessorDecl *accessor, SILValue selfValue,
277
- SILType selfTy, RValue &&initialValue) {
275
+ static void
276
+ emitApplyOfInitAccessor (SILGenFunction &SGF, SILLocation loc,
277
+ AccessorDecl *accessor, SILValue selfValue,
278
+ SILType selfTy, RValue &&initialValue) {
278
279
SmallVector<SILValue> arguments;
279
280
280
- auto emitFieldReference = [&](VarDecl *field) {
281
+ auto emitFieldReference = [&](VarDecl *field, bool forInit = false ) {
281
282
auto fieldTy =
282
283
selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
283
284
return SGF.B .createStructElementAddr (loc, selfValue, field,
@@ -287,7 +288,7 @@ static void emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc,
287
288
// First, let's emit all of the indirect results.
288
289
if (auto *initAttr = accessor->getAttrs ().getAttribute <InitializesAttr>()) {
289
290
for (auto *property : initAttr->getPropertyDecls (accessor)) {
290
- arguments.push_back (emitFieldReference (property));
291
+ arguments.push_back (emitFieldReference (property, /* forInit= */ true ));
291
292
}
292
293
}
293
294
@@ -399,29 +400,39 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
399
400
400
401
// If we have an indirect return slot, initialize it in-place.
401
402
if (resultSlot) {
402
- // Tracks all the init accessors we have emitted
403
- // because they can initialize more than one property.
404
- llvm::SmallPtrSet<AccessorDecl *, 2 > emittedInitAccessors;
405
-
406
403
auto elti = elements.begin (), eltEnd = elements.end ();
407
- for (VarDecl *field : decl->getStoredProperties ()) {
404
+
405
+ llvm::SmallPtrSet<VarDecl *, 4 > storedProperties;
406
+ {
407
+ auto properties = decl->getStoredProperties ();
408
+ storedProperties.insert (properties.begin (), properties.end ());
409
+ }
410
+
411
+ for (auto *member : decl->getMembers ()) {
412
+ auto *field = dyn_cast<VarDecl>(member);
413
+ if (!field)
414
+ continue ;
415
+
416
+ if (initializedViaAccessor.count (field))
417
+ continue ;
408
418
409
419
// Handle situations where this stored propery is initialized
410
420
// via a call to an init accessor on some other property.
411
- if (initializedViaAccessor.count (field)) {
412
- auto *initProperty = initializedViaAccessor.find (field)->second ;
413
- auto *initAccessor = initProperty->getAccessor (AccessorKind::Init);
414
-
415
- if (emittedInitAccessors.count (initAccessor))
421
+ if (auto *initAccessor = field->getAccessor (AccessorKind::Init)) {
422
+ if (field->isMemberwiseInitialized (/* preferDeclaredProperties=*/ true )) {
423
+ assert (elti != eltEnd &&
424
+ " number of args does not match number of fields" );
425
+
426
+ emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot, selfTy,
427
+ std::move (*elti));
428
+ ++elti;
416
429
continue ;
430
+ }
431
+ }
417
432
418
- emitApplyOfInitAccessor (SGF, Loc, initAccessor, resultSlot, selfTy,
419
- std::move (*elti));
420
-
421
- emittedInitAccessors.insert (initAccessor);
422
- ++elti;
433
+ // If this is not one of the stored properties, let's move on.
434
+ if (!storedProperties.count (field))
423
435
continue ;
424
- }
425
436
426
437
auto fieldTy =
427
438
selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
0 commit comments