@@ -520,34 +520,47 @@ static void emitCaptureArguments(SILGenFunction &SGF,
520
520
auto &lowering = SGF.getTypeLowering (type);
521
521
// Constant decls are captured by value.
522
522
SILType ty = lowering.getLoweredType ();
523
- SILValue val = SGF.F .begin ()->createFunctionArgument (ty, VD);
524
-
525
- bool NeedToDestroyValueAtExit = false ;
523
+ ManagedValue val = ManagedValue::forUnmanaged (
524
+ SGF.F .begin ()->createFunctionArgument (ty, VD));
526
525
527
526
// If the original variable was settable, then Sema will have treated the
528
527
// VarDecl as an lvalue, even in the closure's use. As such, we need to
529
528
// allow formation of the address for this captured value. Create a
530
529
// temporary within the closure to provide this address.
531
530
if (VD->isSettable (VD->getDeclContext ())) {
532
- auto addr = SGF.emitTemporaryAllocation (VD, ty );
531
+ auto addr = SGF.emitTemporary (VD, lowering );
533
532
// We have created a copy that needs to be destroyed.
534
533
val = SGF.B .emitCopyValueOperation (Loc, val);
535
- NeedToDestroyValueAtExit = true ;
536
- lowering.emitStore (SGF.B , VD, val, addr, StoreOwnershipQualifier::Init);
537
- val = addr;
534
+ // We use the SILValue version of this because the SILGenBuilder version
535
+ // will create a cloned cleanup, which we do not want since our temporary
536
+ // already has a cleanup.
537
+ //
538
+ // MG: Is this the right semantics for createStore? Seems like that
539
+ // should be potentially a different API.
540
+ SGF.B .emitStoreValueOperation (VD, val.forward (SGF), addr->getAddress (),
541
+ StoreOwnershipQualifier::Init);
542
+ addr->finishInitialization (SGF);
543
+ val = addr->getManagedAddress ();
544
+ }
545
+
546
+ // If this constant is a move only type, we need to add no_copy checking to
547
+ // ensure that we do not consume this captured value in the function. This
548
+ // is because closures can be invoked multiple times which is inconsistent
549
+ // with consuming the move only type.
550
+ if (val.getType ().isMoveOnly ()) {
551
+ val = val.ensurePlusOne (SGF, Loc);
552
+ val = SGF.B .createMarkMustCheckInst (Loc, val,
553
+ MarkMustCheckInst::CheckKind::NoCopy);
538
554
}
539
555
540
- SGF.VarLocs [VD] = SILGenFunction::VarLoc::get (val);
541
- if (auto *AllocStack = dyn_cast<AllocStackInst>(val))
556
+ SGF.VarLocs [VD] = SILGenFunction::VarLoc::get (val. getValue () );
557
+ if (auto *AllocStack = dyn_cast<AllocStackInst>(val. getValue ())) {
542
558
AllocStack->setArgNo (ArgNo);
543
- else {
559
+ } else {
544
560
SILDebugVariable DbgVar (VD->isLet (), ArgNo);
545
- SGF.B .createDebugValue (Loc, val, DbgVar);
561
+ SGF.B .createDebugValue (Loc, val. getValue () , DbgVar);
546
562
}
547
563
548
- // TODO: Closure contexts should always be guaranteed.
549
- if (NeedToDestroyValueAtExit && !lowering.isTrivial ())
550
- SGF.enterDestroyCleanup (val);
551
564
break ;
552
565
}
553
566
0 commit comments