@@ -925,6 +925,8 @@ void LifetimeChecker::injectActorHopForBlock(
925
925
injectHopToExecutorAfter (loc, bbi, TheMemory.getUninitializedValue ());
926
926
}
927
927
928
+ static bool isFailableInitReturnUseOfEnum (EnumInst *EI);
929
+
928
930
void LifetimeChecker::injectActorHops () {
929
931
auto ctor = TheMemory.getActorInitSelf ();
930
932
@@ -947,11 +949,36 @@ void LifetimeChecker::injectActorHops() {
947
949
// Returns true iff a block returns normally from the initializer,
948
950
// which means that it returns `self` in some way (perhaps optional-wrapped).
949
951
auto returnsSelf = [](SILBasicBlock &block) -> bool {
950
- // This check relies on the fact that failable initializers are emitted by
951
- // SILGen to perform their return in a fresh block with either:
952
- // 1. No non-load uses of `self` (e.g., failing case)
953
- // 2. An all-Yes in-availability. (e.g., success case)
954
- return block.getTerminator ()->getTermKind () == TermKind::ReturnInst;
952
+ auto term = block.getTerminator ();
953
+ auto kind = term->getTermKind ();
954
+
955
+ // Does this block return directly?
956
+ if (kind == TermKind::ReturnInst)
957
+ return true ;
958
+
959
+
960
+ // Does this block return `self` wrapped in an Optional?
961
+ // The pattern would look like:
962
+ //
963
+ // thisBB:
964
+ // ...
965
+ // %x = enum $Optional<Dactor>, #Optional.some!enumelt
966
+ // br exitBB(%x : $Optional<Dactor>)
967
+ //
968
+ // exitBB(%y : $Optional<Dactor>):
969
+ // return %y : $Optional<Dactor>
970
+ //
971
+ if (kind == TermKind::BranchInst)
972
+ if (term->getNumOperands () == 1 )
973
+ if (auto *passedVal = term->getOperand (0 )->getDefiningInstruction ())
974
+ if (auto *ei = dyn_cast<EnumInst>(passedVal))
975
+ if (isFailableInitReturnUseOfEnum (ei))
976
+ // Once we've reached this point, we know it's an Optional enum.
977
+ // To determine whether it's .some or .none, we can just check
978
+ // the number of operands.
979
+ return ei->getNumOperands () == 1 ; // is it .some ?
980
+
981
+ return false ;
955
982
};
956
983
957
984
// ///
0 commit comments