@@ -430,7 +430,7 @@ class PackExpansionResultPlan : public ResultPlan {
430430public:
431431 PackExpansionResultPlan (ResultPlanBuilder &builder,
432432 SILValue packAddr,
433- Optional<MutableArrayRef<InitializationPtr >> inits,
433+ Optional<ArrayRef<Initialization* >> inits,
434434 AbstractionPattern origExpansionType,
435435 CanTupleEltTypeArrayRef substEltTypes)
436436 : PackAddr(packAddr) {
@@ -443,7 +443,7 @@ class PackExpansionResultPlan : public ResultPlan {
443443
444444 ComponentPlans.reserve (substEltTypes.size ());
445445 for (auto i : indices (substEltTypes)) {
446- Initialization *init = inits ? (*inits)[i]. get () : nullptr ;
446+ Initialization *init = inits ? (*inits)[i] : nullptr ;
447447 CanType substEltType = substEltTypes[i];
448448
449449 if (isa<PackExpansionType>(substEltType)) {
@@ -635,33 +635,49 @@ class TupleRValueResultPlan final : public ResultPlan {
635635class TupleInitializationResultPlan final : public ResultPlan {
636636 Initialization *tupleInit;
637637 SmallVector<InitializationPtr, 4 > eltInitsBuffer;
638- MutableArrayRef<InitializationPtr> eltInits;
639638 SmallVector<ResultPlanPtr, 4 > eltPlans;
639+ bool origTupleVanishes;
640640
641641public:
642642 TupleInitializationResultPlan (ResultPlanBuilder &builder,
643643 Initialization *tupleInit,
644644 AbstractionPattern origType,
645- CanType substType)
646- : tupleInit(tupleInit) {
645+ CanType substType,
646+ bool origTupleVanishes)
647+ : tupleInit(tupleInit), origTupleVanishes(origTupleVanishes) {
648+
647649 // Get the sub-initializations.
648- eltInits = tupleInit->splitIntoTupleElements (builder.SGF , builder.loc ,
649- substType, eltInitsBuffer);
650+ SmallVector<Initialization*, 4 > eltInits;
651+ if (origTupleVanishes) {
652+ eltInits.push_back (tupleInit);
653+ } else {
654+ MutableArrayRef<InitializationPtr> ownedEltInits
655+ = tupleInit->splitIntoTupleElements (builder.SGF , builder.loc ,
656+ substType, eltInitsBuffer);
657+
658+ // The ownership of these inits is maintained in eltInitsBuffer
659+ // (or tupleInit internally), but we need to create a temporary
660+ // array of unowned references to the inits, after which we can
661+ // throw away the ArrayRef that was returned to us.
662+ eltInits.reserve (ownedEltInits.size ());
663+ for (auto &eltInit : ownedEltInits) {
664+ eltInits.push_back (eltInit.get ());
665+ }
666+ }
650667
651668 // Create plans for all the sub-initializations.
652669 eltPlans.reserve (origType.getNumTupleElements ());
653-
654670 origType.forEachTupleElement (substType,
655671 [&](TupleElementGenerator &elt) {
656672 auto origEltType = elt.getOrigType ();
657673 auto substEltTypes = elt.getSubstTypes ();
658674 if (!elt.isOrigPackExpansion ()) {
659- Initialization *eltInit = eltInits[elt.getSubstIndex ()]. get () ;
675+ Initialization *eltInit = eltInits[elt.getSubstIndex ()];
660676 eltPlans.push_back (builder.build (eltInit, origEltType,
661677 substEltTypes[0 ]));
662678 } else {
663- auto componentInits =
664- eltInits .slice (elt.getSubstIndex (), substEltTypes.size ());
679+ auto componentInits = llvm::makeArrayRef (eltInits)
680+ .slice (elt.getSubstIndex (), substEltTypes.size ());
665681 eltPlans.push_back (builder.buildForPackExpansion (componentInits,
666682 origEltType,
667683 substEltTypes));
@@ -678,7 +694,12 @@ class TupleInitializationResultPlan final : public ResultPlan {
678694 assert (eltRV.isInContext ());
679695 (void )eltRV;
680696 }
681- tupleInit->finishInitialization (SGF);
697+
698+ // Finish the tuple initialization; but if the tuple vanished,
699+ // this is handled in the loop above.
700+ if (!origTupleVanishes) {
701+ tupleInit->finishInitialization (SGF);
702+ }
682703
683704 return RValue::forInContext ();
684705 }
@@ -1179,7 +1200,7 @@ ResultPlanPtr ResultPlanBuilder::buildForScalar(Initialization *init,
11791200}
11801201
11811202ResultPlanPtr ResultPlanBuilder::
1182- buildForPackExpansion (Optional<MutableArrayRef<InitializationPtr >> inits,
1203+ buildForPackExpansion (Optional<ArrayRef<Initialization* >> inits,
11831204 AbstractionPattern origExpansionType,
11841205 CanTupleEltTypeArrayRef substTypes) {
11851206 assert (!inits || inits->size () == substTypes.size ());
@@ -1301,10 +1322,16 @@ ResultPlanBuilder::buildScalarIntoPack(SILValue packAddr,
13011322ResultPlanPtr ResultPlanBuilder::buildForTuple (Initialization *init,
13021323 AbstractionPattern origType,
13031324 CanType substType) {
1304- // If we have an initialization, and we can split it, do so.
1305- if (init && init->canSplitIntoTupleElements ()) {
1306- return ResultPlanPtr (
1307- new TupleInitializationResultPlan (*this , init, origType, substType));
1325+ // If we have an initialization, and we can split the initialization,
1326+ // emit directly into the initialization. If the orig tuple vanishes,
1327+ // that counts as the initialization being splittable.
1328+ if (init) {
1329+ bool vanishes = origType.getVanishingTupleElementPatternType ().hasValue ();
1330+ if (vanishes || init->canSplitIntoTupleElements ()) {
1331+ return ResultPlanPtr (
1332+ new TupleInitializationResultPlan (*this , init, origType, substType,
1333+ vanishes));
1334+ }
13081335 }
13091336
13101337 auto substTupleType = dyn_cast<TupleType>(substType);
0 commit comments