@@ -587,13 +587,26 @@ class PartitionOpTranslator {
587587 }
588588#endif
589589
590+ enum SILMultiAssignFlags : uint8_t {
591+ None = 0x0 ,
592+
593+ // / Set to true if this SILMultiAssign call should assume that we are
594+ // / creating a new value that is guaranteed to be propagating actor self.
595+ // /
596+ // / As an example, this is used when a partial_apply captures an actor. Even
597+ // / though we are doing an assign fresh, we want to make sure that the
598+ // / closure is viewed as coming from an actor.
599+ PropagatesActorSelf = 0x1 ,
600+ };
601+ using SILMultiAssignOptions = OptionSet<SILMultiAssignFlags>;
602+
590603 // / Require all non-sendable sources, merge their regions, and assign the
591604 // / resulting region to all non-sendable targets, or assign non-sendable
592605 // / targets to a fresh region if there are no non-sendable sources.
593606 template <typename TargetRange, typename SourceRange>
594607 void translateSILMultiAssign (const TargetRange &resultValues,
595608 const SourceRange &sourceValues,
596- bool propagagesActorSelf = false ) {
609+ SILMultiAssignOptions options = {} ) {
597610 REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs ()
598611 << " Performing Multi Assign!\n " );
599612 SmallVector<SILValue, 8 > assignOperands;
@@ -611,7 +624,7 @@ class PartitionOpTranslator {
611624 REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs () << " Result: " << *result);
612625 assignResults.push_back (value->getRepresentative ());
613626 // TODO: Can we pass back a reference to value perhaps?
614- if (propagagesActorSelf ) {
627+ if (options. contains (SILMultiAssignFlags::PropagatesActorSelf) ) {
615628 markValueAsActorDerived (result);
616629 }
617630 }
@@ -654,26 +667,26 @@ class PartitionOpTranslator {
654667 // If this apply does not cross isolation domains, it has normal
655668 // non-transferring multi-assignment semantics
656669 if (!SILApplyCrossesIsolation (applyInst)) {
657- // TODO: How do we handle partial_apply here.
658- bool hasActorSelf = false ;
670+ SILMultiAssignOptions options;
659671 if (auto fas = FullApplySite::isa (applyInst)) {
660672 if (fas.hasSelfArgument ()) {
661673 if (auto self = fas.getSelfArgument ()) {
662- hasActorSelf = self->getType ().isActor ();
674+ if (self->getType ().isActor ())
675+ options |= SILMultiAssignFlags::PropagatesActorSelf;
663676 }
664677 }
665678 } else if (auto *pai = dyn_cast<PartialApplyInst>(applyInst)) {
666679 for (auto arg : pai->getOperandValues ()) {
667680 if (auto value = tryToTrackValue (arg)) {
668681 if (value->isActorDerived ()) {
669- hasActorSelf = true ;
682+ options |= SILMultiAssignFlags::PropagatesActorSelf ;
670683 }
671684 } else {
672685 // NOTE: One may think that only sendable things can enter
673686 // here... but we treat things like function_ref/class_method which
674687 // are non-Sendable as sendable for our purposes.
675688 if (arg->getType ().isActor ()) {
676- hasActorSelf = true ;
689+ options |= SILMultiAssignFlags::PropagatesActorSelf ;
677690 }
678691 }
679692 }
@@ -682,7 +695,7 @@ class PartitionOpTranslator {
682695 SmallVector<SILValue, 8 > applyResults;
683696 getApplyResults (applyInst, applyResults);
684697 return translateSILMultiAssign (
685- applyResults, applyInst->getOperandValues (), hasActorSelf );
698+ applyResults, applyInst->getOperandValues (), options );
686699 }
687700
688701 if (auto cast = dyn_cast<ApplyInst>(applyInst))
0 commit comments