@@ -272,12 +272,13 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
272272 subs, std::move (arg));
273273}
274274
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) {
278279 SmallVector<SILValue> arguments;
279280
280- auto emitFieldReference = [&](VarDecl *field) {
281+ auto emitFieldReference = [&](VarDecl *field, bool forInit = false ) {
281282 auto fieldTy =
282283 selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
283284 return SGF.B .createStructElementAddr (loc, selfValue, field,
@@ -287,7 +288,7 @@ static void emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc,
287288 // First, let's emit all of the indirect results.
288289 if (auto *initAttr = accessor->getAttrs ().getAttribute <InitializesAttr>()) {
289290 for (auto *property : initAttr->getPropertyDecls (accessor)) {
290- arguments.push_back (emitFieldReference (property));
291+ arguments.push_back (emitFieldReference (property, /* forInit= */ true ));
291292 }
292293 }
293294
@@ -399,29 +400,39 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
399400
400401 // If we have an indirect return slot, initialize it in-place.
401402 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-
406403 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 ;
408418
409419 // Handle situations where this stored propery is initialized
410420 // 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;
416429 continue ;
430+ }
431+ }
417432
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))
423435 continue ;
424- }
425436
426437 auto fieldTy =
427438 selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
0 commit comments