@@ -505,10 +505,24 @@ void SILGenFunction::emitCaptures(SILLocation loc,
505505 }
506506
507507 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);
510524 auto valueType = FunctionDC->mapTypeIntoContext (
511- vd-> getValueInterfaceType ());
525+ interfaceType-> getReferenceStorageReferent ());
512526
513527 //
514528 // If we haven't emitted the captured value yet, we're forming a closure
@@ -571,8 +585,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
571585
572586 // Get an address value for a SILValue if it is address only in an type
573587 // 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 {
576589 if (SGM.M .useLoweredAddresses ()
577590 && SGM.Types
578591 .getTypeLowering (
@@ -582,32 +595,62 @@ void SILGenFunction::emitCaptures(SILLocation loc,
582595 .isAddressOnly ()
583596 && !entryValue->getType ().isAddress ()) {
584597
598+ assert (!isPack);
599+
585600 auto addr = emitTemporaryAllocation (vd, entryValue->getType (), false ,
586601 false , /* generateDebugInfo*/ false );
587602 auto val = B.emitCopyValueOperation (loc, entryValue);
588603 auto &lowering = getTypeLowering (entryValue->getType ());
589604 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;
592633 }
593- return entryValue;
594634 };
595635
596636 auto Entry = found->second ;
637+ auto val = Entry.value ;
638+
597639 switch (SGM.Types .getDeclCaptureKind (capture, expansion)) {
598640 case CaptureKind::Constant: {
641+ assert (!isPack);
642+
599643 // let declarations.
600644 auto &tl = getTypeLowering (valueType);
601- SILValue Val = Entry.value ;
602645 bool eliminateMoveOnlyWrapper =
603- Val ->getType ().isMoveOnlyWrapped () &&
604- !vd-> getInterfaceType () ->is <SILMoveOnlyWrappedType>();
646+ val ->getType ().isMoveOnlyWrapped () &&
647+ !interfaceType ->is <SILMoveOnlyWrappedType>();
605648
606- if (!Val ->getType ().isAddress ()) {
649+ if (!val ->getType ().isAddress ()) {
607650 // Our 'let' binding can guarantee the lifetime for the callee,
608651 // if we don't need to do anything more to it.
609652 if (canGuarantee && !vd->getInterfaceType ()->is <ReferenceStorageType>()) {
610- auto guaranteed = ManagedValue::forUnmanaged (Val ).borrow (*this , loc);
653+ auto guaranteed = ManagedValue::forUnmanaged (val ).borrow (*this , loc);
611654 if (eliminateMoveOnlyWrapper)
612655 guaranteed = B.createGuaranteedMoveOnlyWrapperToCopyableValue (
613656 loc, guaranteed);
@@ -616,64 +659,63 @@ void SILGenFunction::emitCaptures(SILLocation loc,
616659 }
617660
618661 // Just copy a by-val let.
619- Val = B.emitCopyValueOperation (loc, Val );
662+ val = B.emitCopyValueOperation (loc, val );
620663 // If we need to unwrap a moveonlywrapped value, do so now but in an
621664 // owned way to ensure that the partial apply is viewed as a semantic
622665 // use of the value.
623666 if (eliminateMoveOnlyWrapper)
624- Val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, Val );
667+ val = B.createOwnedMoveOnlyWrapperToCopyableValue (loc, val );
625668 } else {
626669 // If we have a mutable binding for a 'let', such as 'self' in an
627670 // '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 ,
631674 MarkMustCheckInst::CheckKind::AssignableButNotConsumable);
632675 }
633- Val = emitLoad (loc, Val , tl, SGFContext (), IsNotTake).forward (*this );
676+ val = emitLoad (loc, val , tl, SGFContext (), IsNotTake).forward (*this );
634677 }
635678
636679 // If we're capturing an unowned pointer by value, we will have just
637680 // loaded it into a normal retained class pointer, but we capture it as
638681 // 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));
641684
642- capturedArgs.push_back (emitManagedRValueWithCleanup (Val ));
685+ capturedArgs.push_back (emitManagedRValueWithCleanup (val ));
643686 break ;
644687 }
645688 case CaptureKind::Immutable: {
646689 if (canGuarantee) {
647690 // No-escaping stored declarations are captured as the
648691 // 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 ));
651694 }
652695 else if (!silConv.useLoweredAddresses ()) {
653696 capturedArgs.push_back (
654- B.createCopyValue (loc, ManagedValue::forUnmanaged (Entry. value )));
697+ B.createCopyValue (loc, ManagedValue::forUnmanaged (val )));
655698 } 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 );
662700 capturedArgs.push_back (ManagedValue::forLValue (addr));
663701 }
664702 break ;
665703 }
666704 case CaptureKind::StorageAddress: {
667- auto entryValue = getAddressValue (Entry);
705+ assert (!isPack);
706+
707+ auto addr = getAddressValue (val, /* forceCopy=*/ false );
668708 // No-escaping stored declarations are captured as the
669709 // 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 ));
672712 break ;
673713 }
674714
675715 case CaptureKind::Box: {
676- auto entryValue = getAddressValue (Entry);
716+ assert (!isPack);
717+
718+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
677719 // LValues are captured as both the box owning the value and the
678720 // address of the value.
679721 assert (entryValue->getType ().isAddress () && " no address for captured var!" );
@@ -722,7 +764,9 @@ void SILGenFunction::emitCaptures(SILLocation loc,
722764 break ;
723765 }
724766 case CaptureKind::ImmutableBox: {
725- auto entryValue = getAddressValue (Entry);
767+ assert (!isPack);
768+
769+ auto entryValue = getAddressValue (val, /* forceCopy=*/ false );
726770 // LValues are captured as both the box owning the value and the
727771 // address of the value.
728772 assert (entryValue->getType ().isAddress () &&
0 commit comments