@@ -587,13 +587,26 @@ class PartitionOpTranslator {
587
587
}
588
588
#endif
589
589
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
+
590
603
// / Require all non-sendable sources, merge their regions, and assign the
591
604
// / resulting region to all non-sendable targets, or assign non-sendable
592
605
// / targets to a fresh region if there are no non-sendable sources.
593
606
template <typename TargetRange, typename SourceRange>
594
607
void translateSILMultiAssign (const TargetRange &resultValues,
595
608
const SourceRange &sourceValues,
596
- bool propagagesActorSelf = false ) {
609
+ SILMultiAssignOptions options = {} ) {
597
610
REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs ()
598
611
<< " Performing Multi Assign!\n " );
599
612
SmallVector<SILValue, 8 > assignOperands;
@@ -611,7 +624,7 @@ class PartitionOpTranslator {
611
624
REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs () << " Result: " << *result);
612
625
assignResults.push_back (value->getRepresentative ());
613
626
// TODO: Can we pass back a reference to value perhaps?
614
- if (propagagesActorSelf ) {
627
+ if (options. contains (SILMultiAssignFlags::PropagatesActorSelf) ) {
615
628
markValueAsActorDerived (result);
616
629
}
617
630
}
@@ -654,26 +667,26 @@ class PartitionOpTranslator {
654
667
// If this apply does not cross isolation domains, it has normal
655
668
// non-transferring multi-assignment semantics
656
669
if (!SILApplyCrossesIsolation (applyInst)) {
657
- // TODO: How do we handle partial_apply here.
658
- bool hasActorSelf = false ;
670
+ SILMultiAssignOptions options;
659
671
if (auto fas = FullApplySite::isa (applyInst)) {
660
672
if (fas.hasSelfArgument ()) {
661
673
if (auto self = fas.getSelfArgument ()) {
662
- hasActorSelf = self->getType ().isActor ();
674
+ if (self->getType ().isActor ())
675
+ options |= SILMultiAssignFlags::PropagatesActorSelf;
663
676
}
664
677
}
665
678
} else if (auto *pai = dyn_cast<PartialApplyInst>(applyInst)) {
666
679
for (auto arg : pai->getOperandValues ()) {
667
680
if (auto value = tryToTrackValue (arg)) {
668
681
if (value->isActorDerived ()) {
669
- hasActorSelf = true ;
682
+ options |= SILMultiAssignFlags::PropagatesActorSelf ;
670
683
}
671
684
} else {
672
685
// NOTE: One may think that only sendable things can enter
673
686
// here... but we treat things like function_ref/class_method which
674
687
// are non-Sendable as sendable for our purposes.
675
688
if (arg->getType ().isActor ()) {
676
- hasActorSelf = true ;
689
+ options |= SILMultiAssignFlags::PropagatesActorSelf ;
677
690
}
678
691
}
679
692
}
@@ -682,7 +695,7 @@ class PartitionOpTranslator {
682
695
SmallVector<SILValue, 8 > applyResults;
683
696
getApplyResults (applyInst, applyResults);
684
697
return translateSILMultiAssign (
685
- applyResults, applyInst->getOperandValues (), hasActorSelf );
698
+ applyResults, applyInst->getOperandValues (), options );
686
699
}
687
700
688
701
if (auto cast = dyn_cast<ApplyInst>(applyInst))
0 commit comments