@@ -430,7 +430,7 @@ class PackExpansionResultPlan : public ResultPlan {
430
430
public:
431
431
PackExpansionResultPlan (ResultPlanBuilder &builder,
432
432
SILValue packAddr,
433
- Optional<MutableArrayRef<InitializationPtr >> inits,
433
+ Optional<ArrayRef<Initialization* >> inits,
434
434
AbstractionPattern origExpansionType,
435
435
CanTupleEltTypeArrayRef substEltTypes)
436
436
: PackAddr(packAddr) {
@@ -443,7 +443,7 @@ class PackExpansionResultPlan : public ResultPlan {
443
443
444
444
ComponentPlans.reserve (substEltTypes.size ());
445
445
for (auto i : indices (substEltTypes)) {
446
- Initialization *init = inits ? (*inits)[i]. get () : nullptr ;
446
+ Initialization *init = inits ? (*inits)[i] : nullptr ;
447
447
CanType substEltType = substEltTypes[i];
448
448
449
449
if (isa<PackExpansionType>(substEltType)) {
@@ -635,33 +635,49 @@ class TupleRValueResultPlan final : public ResultPlan {
635
635
class TupleInitializationResultPlan final : public ResultPlan {
636
636
Initialization *tupleInit;
637
637
SmallVector<InitializationPtr, 4 > eltInitsBuffer;
638
- MutableArrayRef<InitializationPtr> eltInits;
639
638
SmallVector<ResultPlanPtr, 4 > eltPlans;
639
+ bool origTupleVanishes;
640
640
641
641
public:
642
642
TupleInitializationResultPlan (ResultPlanBuilder &builder,
643
643
Initialization *tupleInit,
644
644
AbstractionPattern origType,
645
- CanType substType)
646
- : tupleInit(tupleInit) {
645
+ CanType substType,
646
+ bool origTupleVanishes)
647
+ : tupleInit(tupleInit), origTupleVanishes(origTupleVanishes) {
648
+
647
649
// 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
+ }
650
667
651
668
// Create plans for all the sub-initializations.
652
669
eltPlans.reserve (origType.getNumTupleElements ());
653
-
654
670
origType.forEachTupleElement (substType,
655
671
[&](TupleElementGenerator &elt) {
656
672
auto origEltType = elt.getOrigType ();
657
673
auto substEltTypes = elt.getSubstTypes ();
658
674
if (!elt.isOrigPackExpansion ()) {
659
- Initialization *eltInit = eltInits[elt.getSubstIndex ()]. get () ;
675
+ Initialization *eltInit = eltInits[elt.getSubstIndex ()];
660
676
eltPlans.push_back (builder.build (eltInit, origEltType,
661
677
substEltTypes[0 ]));
662
678
} else {
663
- auto componentInits =
664
- eltInits .slice (elt.getSubstIndex (), substEltTypes.size ());
679
+ auto componentInits = llvm::makeArrayRef (eltInits)
680
+ .slice (elt.getSubstIndex (), substEltTypes.size ());
665
681
eltPlans.push_back (builder.buildForPackExpansion (componentInits,
666
682
origEltType,
667
683
substEltTypes));
@@ -678,7 +694,12 @@ class TupleInitializationResultPlan final : public ResultPlan {
678
694
assert (eltRV.isInContext ());
679
695
(void )eltRV;
680
696
}
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
+ }
682
703
683
704
return RValue::forInContext ();
684
705
}
@@ -1179,7 +1200,7 @@ ResultPlanPtr ResultPlanBuilder::buildForScalar(Initialization *init,
1179
1200
}
1180
1201
1181
1202
ResultPlanPtr ResultPlanBuilder::
1182
- buildForPackExpansion (Optional<MutableArrayRef<InitializationPtr >> inits,
1203
+ buildForPackExpansion (Optional<ArrayRef<Initialization* >> inits,
1183
1204
AbstractionPattern origExpansionType,
1184
1205
CanTupleEltTypeArrayRef substTypes) {
1185
1206
assert (!inits || inits->size () == substTypes.size ());
@@ -1301,10 +1322,16 @@ ResultPlanBuilder::buildScalarIntoPack(SILValue packAddr,
1301
1322
ResultPlanPtr ResultPlanBuilder::buildForTuple (Initialization *init,
1302
1323
AbstractionPattern origType,
1303
1324
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
+ }
1308
1335
}
1309
1336
1310
1337
auto substTupleType = dyn_cast<TupleType>(substType);
0 commit comments