@@ -1316,6 +1316,7 @@ FirstArgOwnershipForwardingSingleValueInst::classof(SILInstructionKind kind) {
13161316 case SILInstructionKind::OpenExistentialRefInst:
13171317 case SILInstructionKind::InitExistentialRefInst:
13181318 case SILInstructionKind::MarkDependenceInst:
1319+ case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
13191320 return true ;
13201321 default :
13211322 return false ;
@@ -7587,6 +7588,60 @@ class MarkMustCheckInst
75877588 bool isNoImplicitCopy () const { return kind == CheckKind::NoImplicitCopy; }
75887589};
75897590
7591+ class CopyableToMoveOnlyWrapperValueInst
7592+ : public UnaryInstructionBase<
7593+ SILInstructionKind::CopyableToMoveOnlyWrapperValueInst,
7594+ SingleValueInstruction> {
7595+ friend class SILBuilder ;
7596+
7597+ CopyableToMoveOnlyWrapperValueInst (SILDebugLocation DebugLoc,
7598+ SILValue operand)
7599+ : UnaryInstructionBase(DebugLoc, operand,
7600+ operand->getType ().addingMoveOnlyWrapper()) {}
7601+ };
7602+
7603+ // / Convert from an @moveOnly wrapper type to the underlying copyable type. Can
7604+ // / be either owned or guaranteed.
7605+ // /
7606+ // / IMPORTANT: Unlike other forwarding instructions, the ownership of moveonly
7607+ // / to copyable is not forwarded from the operand. Instead in SILBuilder one
7608+ // / must select the specific type of ownership one wishes by using the following
7609+ // / APIs:
7610+ // /
7611+ // / * SILBuilder::createOwnedMoveOnlyWrapperToCopyableValueInst
7612+ // / * SILBuilder::createGuaranteedMoveOnlyWrapperToCopyableValueInst
7613+ // /
7614+ // / The reason why this instruction was designed in this manner is that a
7615+ // / frontend chooses the ownership form of this instruction based off of the
7616+ // / semantic place that the value is used. As an example:
7617+ // /
7618+ // / 1. When calling a function semantically with guaranteed ownership, the
7619+ // / frontend would use the "guaranteed variant".
7620+ // /
7621+ // / 2. When returning a value or assigning into another binding, a frontend
7622+ // / would want to use the owned variant so that the move only checker will
7623+ // / enforce the end of the moved value's lifetime.
7624+ // /
7625+ // / NOTE: With time, we are going to eliminate the guaranteed form of this
7626+ // / instruction in favor of a function conversion instruction.
7627+ class MoveOnlyWrapperToCopyableValueInst
7628+ : public UnaryInstructionBase<
7629+ SILInstructionKind::MoveOnlyWrapperToCopyableValueInst,
7630+ SingleValueInstruction>,
7631+ public OwnershipForwardingMixin {
7632+ friend class SILBuilder ;
7633+
7634+ MoveOnlyWrapperToCopyableValueInst (const SILFunction &fn,
7635+ SILDebugLocation DebugLoc,
7636+ SILValue operand,
7637+ OwnershipKind forwardingOwnershipKind)
7638+ : UnaryInstructionBase(DebugLoc, operand,
7639+ operand->getType ().removingMoveOnlyWrapper()),
7640+ OwnershipForwardingMixin(
7641+ SILInstructionKind::MoveOnlyWrapperToCopyableValueInst,
7642+ forwardingOwnershipKind) {}
7643+ };
7644+
75907645// / Given an object reference, return true iff it is non-nil and refers
75917646// / to a native swift object with strong reference count of 1.
75927647class IsUniqueInst
@@ -9728,7 +9783,8 @@ inline bool OwnershipForwardingMixin::isa(SILInstructionKind kind) {
97289783 OwnershipForwardingConversionInst::classof (kind) ||
97299784 OwnershipForwardingSelectEnumInstBase::classof (kind) ||
97309785 OwnershipForwardingMultipleValueInstruction::classof (kind) ||
9731- kind == SILInstructionKind::MarkMustCheckInst;
9786+ kind == SILInstructionKind::MarkMustCheckInst ||
9787+ kind == SILInstructionKind::MoveOnlyWrapperToCopyableValueInst;
97329788}
97339789
97349790inline OwnershipForwardingMixin *
@@ -9752,6 +9808,8 @@ OwnershipForwardingMixin::get(SILInstruction *inst) {
97529808 return result;
97539809 if (auto *result = dyn_cast<MarkMustCheckInst>(inst))
97549810 return result;
9811+ if (auto *result = dyn_cast<MoveOnlyWrapperToCopyableValueInst>(inst))
9812+ return result;
97559813 return nullptr ;
97569814}
97579815
0 commit comments