@@ -520,10 +520,24 @@ void SILGenFunction::emitCaptures(SILLocation loc,
520520 }
521521
522522 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);
525539 auto valueType = FunctionDC->mapTypeIntoContext (
526- vd-> getValueInterfaceType ());
540+ interfaceType-> getReferenceStorageReferent ());
527541
528542 //
529543 // If we haven't emitted the captured value yet, we're forming a closure
@@ -586,8 +600,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
586600
587601 // Get an address value for a SILValue if it is address only in an type
588602 // 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 {
591604 if (SGM.M .useLoweredAddresses ()
592605 && SGM.Types
593606 .getTypeLowering (
@@ -597,32 +610,62 @@ void SILGenFunction::emitCaptures(SILLocation loc,
597610 .isAddressOnly ()
598611 && !entryValue->getType ().isAddress ()) {
599612
613+ assert (!isPack);
614+
600615 auto addr = emitTemporaryAllocation (vd, entryValue->getType (), false ,
601616 false , /* generateDebugInfo*/ false );
602617 auto val = B.emitCopyValueOperation (loc, entryValue);
603618 auto &lowering = getTypeLowering (entryValue->getType ());
604619 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;
607648 }
608- return entryValue;
609649 };
610650
611651 auto Entry = found->second ;
652+ auto val = Entry.value ;
653+
612654 switch (SGM.Types .getDeclCaptureKind (capture, expansion)) {
613655 case CaptureKind::Constant: {
656+ assert (!isPack);
657+
614658 // let declarations.
615659 auto &tl = getTypeLowering (valueType);
616- SILValue Val = Entry.value ;
617660 bool eliminateMoveOnlyWrapper =
618- Val ->getType ().isMoveOnlyWrapped () &&
619- !vd-> getInterfaceType () ->is <SILMoveOnlyWrappedType>();
661+ val ->getType ().isMoveOnlyWrapped () &&
662+ !interfaceType ->is <SILMoveOnlyWrappedType>();
620663
621- if (!Val ->getType ().isAddress ()) {
664+ if (!val ->getType ().isAddress ()) {
622665 // Our 'let' binding can guarantee the lifetime for the callee,
623666 // if we don't need to do anything more to it.
624667 if (canGuarantee && !vd->getInterfaceType ()->is <ReferenceStorageType>()) {
625- auto guaranteed = ManagedValue::forUnmanaged (Val ).borrow (*this , loc);
668+ auto guaranteed = ManagedValue::forUnmanaged (val ).borrow (*this , loc);
626669 if (eliminateMoveOnlyWrapper)
627670 guaranteed = B.createGuaranteedMoveOnlyWrapperToCopyableValue (
628671 loc, guaranteed);
@@ -631,64 +674,63 @@ void SILGenFunction::emitCaptures(SILLocation loc,
631674 }
632675
633676 // Just copy a by-val let.
634- Val = B.emitCopyValueOperation (loc, Val );
677+ val = B.emitCopyValueOperation (loc, val );
635678 // If we need to unwrap a moveonlywrapped value, do so now but in an
636679 // owned way to ensure that the partial apply is viewed as a semantic
637680 // use of the value.
638681 if (eliminateMoveOnlyWrapper)
639- Val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, Val );
682+ val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, val );
640683 } else {
641684 // If we have a mutable binding for a 'let', such as 'self' in an
642685 // '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 ,
646689 MarkMustCheckInst::CheckKind::AssignableButNotConsumable);
647690 }
648- Val = emitLoad (loc, Val , tl, SGFContext (), IsNotTake).forward (*this );
691+ val = emitLoad (loc, val , tl, SGFContext (), IsNotTake).forward (*this );
649692 }
650693
651694 // If we're capturing an unowned pointer by value, we will have just
652695 // loaded it into a normal retained class pointer, but we capture it as
653696 // 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));
656699
657- capturedArgs.push_back (emitManagedRValueWithCleanup (Val ));
700+ capturedArgs.push_back (emitManagedRValueWithCleanup (val ));
658701 break ;
659702 }
660703 case CaptureKind::Immutable: {
661704 if (canGuarantee) {
662705 // No-escaping stored declarations are captured as the
663706 // 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 ));
666709 }
667710 else if (!silConv.useLoweredAddresses ()) {
668711 capturedArgs.push_back (
669- B.createCopyValue (loc, ManagedValue::forUnmanaged (Entry. value )));
712+ B.createCopyValue (loc, ManagedValue::forUnmanaged (val )));
670713 } 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 );
677715 capturedArgs.push_back (ManagedValue::forLValue (addr));
678716 }
679717 break ;
680718 }
681719 case CaptureKind::StorageAddress: {
682- auto entryValue = getAddressValue (Entry);
720+ assert (!isPack);
721+
722+ auto addr = getAddressValue (val, /* forceCopy=*/ false );
683723 // No-escaping stored declarations are captured as the
684724 // 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 ));
687727 break ;
688728 }
689729
690730 case CaptureKind::Box: {
691- auto entryValue = getAddressValue (Entry);
731+ assert (!isPack);
732+
733+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
692734 // LValues are captured as both the box owning the value and the
693735 // address of the value.
694736 assert (entryValue->getType ().isAddress () && " no address for captured var!" );
@@ -737,7 +779,9 @@ void SILGenFunction::emitCaptures(SILLocation loc,
737779 break ;
738780 }
739781 case CaptureKind::ImmutableBox: {
740- auto entryValue = getAddressValue (Entry);
782+ assert (!isPack);
783+
784+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
741785 // LValues are captured as both the box owning the value and the
742786 // address of the value.
743787 assert (entryValue->getType ().isAddress () &&
0 commit comments