@@ -505,10 +505,24 @@ void SILGenFunction::emitCaptures(SILLocation loc,
505
505
}
506
506
507
507
auto *vd = cast<VarDecl>(capture.getDecl ());
508
- auto type = FunctionDC->mapTypeIntoContext (
509
- vd->getInterfaceType ());
508
+
509
+ auto interfaceType = vd->getInterfaceType ();
510
+
511
+ bool isPack = false ;
512
+ if (interfaceType->is <PackExpansionType>()) {
513
+ assert (!vd->supportsMutation () &&
514
+ " Cannot capture a pack as an lvalue" );
515
+
516
+ SmallVector<TupleTypeElt, 1 > elts;
517
+ elts.push_back (interfaceType);
518
+ interfaceType = TupleType::get (elts, getASTContext ());
519
+
520
+ isPack = true ;
521
+ }
522
+
523
+ auto type = FunctionDC->mapTypeIntoContext (interfaceType);
510
524
auto valueType = FunctionDC->mapTypeIntoContext (
511
- vd-> getValueInterfaceType ());
525
+ interfaceType-> getReferenceStorageReferent ());
512
526
513
527
//
514
528
// If we haven't emitted the captured value yet, we're forming a closure
@@ -571,8 +585,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
571
585
572
586
// Get an address value for a SILValue if it is address only in an type
573
587
// expansion context without opaque archetype substitution.
574
- auto getAddressValue = [&](VarLoc entryVarLoc) -> SILValue {
575
- SILValue entryValue = entryVarLoc.value ;
588
+ auto getAddressValue = [&](SILValue entryValue, bool forceCopy) -> SILValue {
576
589
if (SGM.M .useLoweredAddresses ()
577
590
&& SGM.Types
578
591
.getTypeLowering (
@@ -582,32 +595,62 @@ void SILGenFunction::emitCaptures(SILLocation loc,
582
595
.isAddressOnly ()
583
596
&& !entryValue->getType ().isAddress ()) {
584
597
598
+ assert (!isPack);
599
+
585
600
auto addr = emitTemporaryAllocation (vd, entryValue->getType (), false ,
586
601
false , /* generateDebugInfo*/ false );
587
602
auto val = B.emitCopyValueOperation (loc, entryValue);
588
603
auto &lowering = getTypeLowering (entryValue->getType ());
589
604
lowering.emitStore (B, loc, val, addr, StoreOwnershipQualifier::Init);
590
- entryValue = addr;
591
- enterDestroyCleanup (addr);
605
+
606
+ if (!forceCopy)
607
+ enterDestroyCleanup (addr);
608
+ return addr;
609
+
610
+ } else if (isPack) {
611
+ SILType ty = getLoweredType (valueType).getObjectType ();
612
+ auto addr = B.createAllocStack (loc, ty);
613
+ enterDeallocStackCleanup (addr);
614
+
615
+ auto formalPackType = cast<TupleType>(valueType->getCanonicalType ())
616
+ .getInducedPackType ();
617
+ copyPackElementsToTuple (loc, addr, entryValue, formalPackType);
618
+
619
+ if (!forceCopy)
620
+ enterDestroyCleanup (addr);
621
+ return addr;
622
+
623
+ } else if (forceCopy) {
624
+ // We cannot pass a valid SILDebugVariable while creating the temp here
625
+ // See rdar://60425582
626
+ auto addr = B.createAllocStack (loc, entryValue->getType ().getObjectType ());
627
+ enterDeallocStackCleanup (addr);
628
+ B.createCopyAddr (loc, entryValue, addr, IsNotTake, IsInitialization);
629
+ return addr;
630
+
631
+ } else {
632
+ return entryValue;
592
633
}
593
- return entryValue;
594
634
};
595
635
596
636
auto Entry = found->second ;
637
+ auto val = Entry.value ;
638
+
597
639
switch (SGM.Types .getDeclCaptureKind (capture, expansion)) {
598
640
case CaptureKind::Constant: {
641
+ assert (!isPack);
642
+
599
643
// let declarations.
600
644
auto &tl = getTypeLowering (valueType);
601
- SILValue Val = Entry.value ;
602
645
bool eliminateMoveOnlyWrapper =
603
- Val ->getType ().isMoveOnlyWrapped () &&
604
- !vd-> getInterfaceType () ->is <SILMoveOnlyWrappedType>();
646
+ val ->getType ().isMoveOnlyWrapped () &&
647
+ !interfaceType ->is <SILMoveOnlyWrappedType>();
605
648
606
- if (!Val ->getType ().isAddress ()) {
649
+ if (!val ->getType ().isAddress ()) {
607
650
// Our 'let' binding can guarantee the lifetime for the callee,
608
651
// if we don't need to do anything more to it.
609
652
if (canGuarantee && !vd->getInterfaceType ()->is <ReferenceStorageType>()) {
610
- auto guaranteed = ManagedValue::forUnmanaged (Val ).borrow (*this , loc);
653
+ auto guaranteed = ManagedValue::forUnmanaged (val ).borrow (*this , loc);
611
654
if (eliminateMoveOnlyWrapper)
612
655
guaranteed = B.createGuaranteedMoveOnlyWrapperToCopyableValue (
613
656
loc, guaranteed);
@@ -616,64 +659,63 @@ void SILGenFunction::emitCaptures(SILLocation loc,
616
659
}
617
660
618
661
// Just copy a by-val let.
619
- Val = B.emitCopyValueOperation (loc, Val );
662
+ val = B.emitCopyValueOperation (loc, val );
620
663
// If we need to unwrap a moveonlywrapped value, do so now but in an
621
664
// owned way to ensure that the partial apply is viewed as a semantic
622
665
// use of the value.
623
666
if (eliminateMoveOnlyWrapper)
624
- Val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, Val );
667
+ val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, val );
625
668
} else {
626
669
// If we have a mutable binding for a 'let', such as 'self' in an
627
670
// 'init' method, load it.
628
- if (Val ->getType ().isMoveOnly ()) {
629
- Val = B.createMarkMustCheckInst (
630
- loc, Val ,
671
+ if (val ->getType ().isMoveOnly ()) {
672
+ val = B.createMarkMustCheckInst (
673
+ loc, val ,
631
674
MarkMustCheckInst::CheckKind::AssignableButNotConsumable);
632
675
}
633
- Val = emitLoad (loc, Val , tl, SGFContext (), IsNotTake).forward (*this );
676
+ val = emitLoad (loc, val , tl, SGFContext (), IsNotTake).forward (*this );
634
677
}
635
678
636
679
// If we're capturing an unowned pointer by value, we will have just
637
680
// loaded it into a normal retained class pointer, but we capture it as
638
681
// an unowned pointer. Convert back now.
639
- if (vd-> getInterfaceType () ->is <ReferenceStorageType>())
640
- Val = emitConversionFromSemanticValue (loc, Val , getLoweredType (type));
682
+ if (interfaceType ->is <ReferenceStorageType>())
683
+ val = emitConversionFromSemanticValue (loc, val , getLoweredType (type));
641
684
642
- capturedArgs.push_back (emitManagedRValueWithCleanup (Val ));
685
+ capturedArgs.push_back (emitManagedRValueWithCleanup (val ));
643
686
break ;
644
687
}
645
688
case CaptureKind::Immutable: {
646
689
if (canGuarantee) {
647
690
// No-escaping stored declarations are captured as the
648
691
// address of the value.
649
- auto entryValue = getAddressValue (Entry );
650
- capturedArgs.push_back (ManagedValue::forBorrowedRValue (entryValue ));
692
+ auto addr = getAddressValue (val, /* forceCopy= */ false );
693
+ capturedArgs.push_back (ManagedValue::forBorrowedRValue (addr ));
651
694
}
652
695
else if (!silConv.useLoweredAddresses ()) {
653
696
capturedArgs.push_back (
654
- B.createCopyValue (loc, ManagedValue::forUnmanaged (Entry. value )));
697
+ B.createCopyValue (loc, ManagedValue::forUnmanaged (val )));
655
698
} else {
656
- auto entryValue = getAddressValue (Entry);
657
- // We cannot pass a valid SILDebugVariable while creating the temp here
658
- // See rdar://60425582
659
- auto addr = B.createAllocStack (loc, entryValue->getType ().getObjectType ());
660
- enterDeallocStackCleanup (addr);
661
- B.createCopyAddr (loc, entryValue, addr, IsNotTake, IsInitialization);
699
+ auto addr = getAddressValue (val, /* forceCopy=*/ true );
662
700
capturedArgs.push_back (ManagedValue::forLValue (addr));
663
701
}
664
702
break ;
665
703
}
666
704
case CaptureKind::StorageAddress: {
667
- auto entryValue = getAddressValue (Entry);
705
+ assert (!isPack);
706
+
707
+ auto addr = getAddressValue (val, /* forceCopy=*/ false );
668
708
// No-escaping stored declarations are captured as the
669
709
// address of the value.
670
- assert (entryValue ->getType ().isAddress () && " no address for captured var!" );
671
- capturedArgs.push_back (ManagedValue::forLValue (entryValue ));
710
+ assert (addr ->getType ().isAddress () && " no address for captured var!" );
711
+ capturedArgs.push_back (ManagedValue::forLValue (addr ));
672
712
break ;
673
713
}
674
714
675
715
case CaptureKind::Box: {
676
- auto entryValue = getAddressValue (Entry);
716
+ assert (!isPack);
717
+
718
+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
677
719
// LValues are captured as both the box owning the value and the
678
720
// address of the value.
679
721
assert (entryValue->getType ().isAddress () && " no address for captured var!" );
@@ -722,7 +764,9 @@ void SILGenFunction::emitCaptures(SILLocation loc,
722
764
break ;
723
765
}
724
766
case CaptureKind::ImmutableBox: {
725
- auto entryValue = getAddressValue (Entry);
767
+ assert (!isPack);
768
+
769
+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
726
770
// LValues are captured as both the box owning the value and the
727
771
// address of the value.
728
772
assert (entryValue->getType ().isAddress () &&
0 commit comments