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