@@ -1343,6 +1343,39 @@ struct PartitionOpEvaluator {
1343
1343
return asImpl ().getRepresentativeValue (element);
1344
1344
}
1345
1345
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
+
1346
1379
// / Apply \p op to the partition op.
1347
1380
void apply (const PartitionOp &op) {
1348
1381
if (shouldEmitVerboseLogging ()) {
@@ -1370,33 +1403,14 @@ struct PartitionOpEvaluator {
1370
1403
assert (p.isTrackingElement (op.getOpArg2 ()) &&
1371
1404
" Assign PartitionOp's source argument should be already tracked" );
1372
1405
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);
1399
1409
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.
1400
1414
p.assignElement (op.getOpArg1 (), op.getOpArg2 ());
1401
1415
return ;
1402
1416
}
@@ -1491,32 +1505,14 @@ struct PartitionOpEvaluator {
1491
1505
p.isTrackingElement (op.getOpArg2 ()) &&
1492
1506
" Merge PartitionOp's arguments should already be tracked" );
1493
1507
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);
1519
1511
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.
1520
1516
p.merge (op.getOpArg1 (), op.getOpArg2 ());
1521
1517
return ;
1522
1518
}
0 commit comments