@@ -1343,6 +1343,39 @@ struct PartitionOpEvaluator {
13431343 return asImpl ().getRepresentativeValue (element);
13441344 }
13451345
1346+ // / See if we are assigning an a non-disconnected value into a 'out
1347+ // / sending' parameter. In such a case, we emit a diagnostic.
1348+ // /
1349+ // / Helper used to handle assignment into sending results in the context of
1350+ // / assigns or merges.
1351+ void handleAssignNonDisconnectedIntoSendingResult (const PartitionOp &op) {
1352+ if (!doesParentFunctionHaveSendingResult (op))
1353+ return ;
1354+
1355+ auto instance = getRepresentativeValue (op.getOpArg1 ());
1356+ if (!instance)
1357+ return ;
1358+
1359+ auto *fArg =
1360+ dyn_cast_or_null<SILFunctionArgument>(instance.maybeGetValue ());
1361+ if (!fArg || !fArg ->getArgumentConvention ().isIndirectOutParameter ())
1362+ return ;
1363+
1364+ auto staticRegionIsolation = getIsolationRegionInfo (op.getOpArg2 ());
1365+ Region srcRegion = p.getRegion (op.getOpArg2 ());
1366+ auto dynamicRegionIsolation = getIsolationRegionInfo (srcRegion);
1367+
1368+ // We can unconditionally getValue here since we can never
1369+ // assign an actor introducing inst.
1370+ auto rep = getRepresentativeValue (op.getOpArg2 ()).getValue ();
1371+ if (dynamicRegionIsolation.isDisconnected () ||
1372+ staticRegionIsolation.isUnsafeNonIsolated ())
1373+ return ;
1374+
1375+ handleError (AssignNeverSendableIntoSendingResultError (
1376+ op, op.getOpArg1 (), fArg , op.getOpArg2 (), rep, dynamicRegionIsolation));
1377+ }
1378+
13461379 // / Apply \p op to the partition op.
13471380 void apply (const PartitionOp &op) {
13481381 if (shouldEmitVerboseLogging ()) {
@@ -1370,33 +1403,14 @@ struct PartitionOpEvaluator {
13701403 assert (p.isTrackingElement (op.getOpArg2 ()) &&
13711404 " Assign PartitionOp's source argument should be already tracked" );
13721405
1373- // See if we are assigning an a non-disconnected value into a 'out
1374- // sending' parameter. In such a case, we emit a diagnostic.
1375- if (doesParentFunctionHaveSendingResult (op)) {
1376- if (auto instance = getRepresentativeValue (op.getOpArg1 ())) {
1377- if (auto value = instance.maybeGetValue ()) {
1378- if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1379- if (fArg ->getArgumentConvention ().isIndirectOutParameter ()) {
1380- auto staticRegionIsolation =
1381- getIsolationRegionInfo (op.getOpArg2 ());
1382- Region srcRegion = p.getRegion (op.getOpArg2 ());
1383- auto dynamicRegionIsolation = getIsolationRegionInfo (srcRegion);
1384-
1385- // We can unconditionally getValue here since we can never
1386- // assign an actor introducing inst.
1387- auto rep = getRepresentativeValue (op.getOpArg2 ()).getValue ();
1388- if (!dynamicRegionIsolation.isDisconnected () &&
1389- !staticRegionIsolation.isUnsafeNonIsolated ()) {
1390- handleError (AssignNeverSendableIntoSendingResultError (
1391- op, op.getOpArg1 (), fArg , op.getOpArg2 (), rep,
1392- dynamicRegionIsolation));
1393- }
1394- }
1395- }
1396- }
1397- }
1398- }
1406+ // First emit any errors if we are assigning a non-disconnected thing into
1407+ // a sending result.
1408+ handleAssignNonDisconnectedIntoSendingResult (op);
13991409
1410+ // Then perform the actual assignment.
1411+ //
1412+ // NOTE: This does not emit any errors on purpose. We rely on requires and
1413+ // other instructions to emit errors.
14001414 p.assignElement (op.getOpArg1 (), op.getOpArg2 ());
14011415 return ;
14021416 }
@@ -1491,32 +1505,14 @@ struct PartitionOpEvaluator {
14911505 p.isTrackingElement (op.getOpArg2 ()) &&
14921506 " Merge PartitionOp's arguments should already be tracked" );
14931507
1494- // See if we are assigning an a non-disconnected value into a 'out
1495- // sending' parameter. In such a case, we emit a diagnostic.
1496- if (doesParentFunctionHaveSendingResult (op)) {
1497- if (auto instance = getRepresentativeValue (op.getOpArg1 ())) {
1498- if (auto value = instance.maybeGetValue ()) {
1499- if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1500- if (fArg ->getArgumentConvention ().isIndirectOutParameter ()) {
1501- auto staticRegionIsolation =
1502- getIsolationRegionInfo (op.getOpArg2 ());
1503- Region srcRegion = p.getRegion (op.getOpArg2 ());
1504- auto dynamicRegionIsolation = getIsolationRegionInfo (srcRegion);
1505- // We can unconditionally getValue here since we can never
1506- // assign an actor introducing inst.
1507- auto rep = getRepresentativeValue (op.getOpArg2 ()).getValue ();
1508- if (!dynamicRegionIsolation.isDisconnected () &&
1509- !staticRegionIsolation.isUnsafeNonIsolated ()) {
1510- handleError (AssignNeverSendableIntoSendingResultError (
1511- op, op.getOpArg1 (), fArg , op.getOpArg2 (), rep,
1512- dynamicRegionIsolation));
1513- }
1514- }
1515- }
1516- }
1517- }
1518- }
1508+ // Emit an error if we are assigning a non-disconnected thing into a
1509+ // sending result.
1510+ handleAssignNonDisconnectedIntoSendingResult (op);
15191511
1512+ // Then perform the actual merge.
1513+ //
1514+ // NOTE: This does not emit any errors on purpose. We rely on requires and
1515+ // other instructions to emit errors.
15201516 p.merge (op.getOpArg1 (), op.getOpArg2 ());
15211517 return ;
15221518 }
0 commit comments