Skip to content

Commit 5d9aa90

Browse files
committed
[region-isolation] Squelch errors from convert_function uses from a Sendable function.
We view the conversion from a Sendable to a non-Sendable function via convert function to produce a new fresh sendable value. We should squelch that error. (cherry picked from commit b786c60)
1 parent 51a2029 commit 5d9aa90

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,28 @@ struct PartitionOpEvaluator {
11761176
}
11771177

11781178
private:
1179+
bool isConvertFunctionFromSendableType(SILValue equivalenceClassRep) const {
1180+
SILValue valueToTest = equivalenceClassRep;
1181+
while (true) {
1182+
if (auto *i = dyn_cast<ThinToThickFunctionInst>(valueToTest)) {
1183+
valueToTest = i->getOperand();
1184+
continue;
1185+
}
1186+
if (auto *i = dyn_cast<ConvertEscapeToNoEscapeInst>(valueToTest)) {
1187+
valueToTest = i->getOperand();
1188+
continue;
1189+
}
1190+
break;
1191+
}
1192+
1193+
auto *cvi = dyn_cast<ConvertFunctionInst>(valueToTest);
1194+
if (!cvi)
1195+
return false;
1196+
1197+
return cvi->getOperand()->getType().isSendable(
1198+
equivalenceClassRep->getFunction());
1199+
}
1200+
11791201
// Private helper that squelches the error if our transfer instruction and our
11801202
// use have the same isolation.
11811203
void handleLocalUseAfterTransferHelper(const PartitionOp &op, Element elt,
@@ -1188,12 +1210,13 @@ struct PartitionOpEvaluator {
11881210
return;
11891211
}
11901212

1191-
// If we have a temporary that is initialized with an unsafe nonisolated
1192-
// value... squelch the error like if we were that value.
1193-
//
1194-
// TODO: This goes away with opaque values.
11951213
if (SILValue equivalenceClassRep =
11961214
getRepresentative(transferringOp->get())) {
1215+
1216+
// If we have a temporary that is initialized with an unsafe nonisolated
1217+
// value... squelch the error like if we were that value.
1218+
//
1219+
// TODO: This goes away with opaque values.
11971220
if (auto *asi = dyn_cast<AllocStackInst>(equivalenceClassRep)) {
11981221
if (SILValue value = getInitOfTemporaryAllocStack(asi)) {
11991222
if (auto elt = getElement(value)) {
@@ -1204,6 +1227,11 @@ struct PartitionOpEvaluator {
12041227
}
12051228
}
12061229
}
1230+
1231+
// See if we have a convert function from a `@Sendable` type. In this
1232+
// case, we want to squelch the error.
1233+
if (isConvertFunctionFromSendableType(equivalenceClassRep))
1234+
return;
12071235
}
12081236

12091237
// If our instruction does not have any isolation info associated with it,
@@ -1228,12 +1256,12 @@ struct PartitionOpEvaluator {
12281256
const PartitionOp &op, Element elt,
12291257
SILDynamicMergedIsolationInfo dynamicMergedIsolationInfo) const {
12301258
if (shouldTryToSquelchErrors()) {
1231-
// If we have a temporary that is initialized with an unsafe nonisolated
1232-
// value... squelch the error like if we were that value.
1233-
//
1234-
// TODO: This goes away with opaque values.
12351259
if (SILValue equivalenceClassRep =
12361260
getRepresentative(op.getSourceOp()->get())) {
1261+
// If we have a temporary that is initialized with an unsafe nonisolated
1262+
// value... squelch the error like if we were that value.
1263+
//
1264+
// TODO: This goes away with opaque values.
12371265
if (auto *asi = dyn_cast<AllocStackInst>(equivalenceClassRep)) {
12381266
if (SILValue value = getInitOfTemporaryAllocStack(asi)) {
12391267
if (auto elt = getElement(value)) {
@@ -1244,6 +1272,11 @@ struct PartitionOpEvaluator {
12441272
}
12451273
}
12461274
}
1275+
1276+
// See if we have a convert function from a `@Sendable` type. In this
1277+
// case, we want to squelch the error.
1278+
if (isConvertFunctionFromSendableType(equivalenceClassRep))
1279+
return;
12471280
}
12481281
}
12491282

test/Concurrency/transfernonsendable_closureliterals_isolationinference.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,11 @@ func test_CallerAsyncInheritsActorContext_CalleeAsyncNonisolated() async {
368368

369369
// CHECK-LABEL: // closure #3 in test_CallerAsyncInheritsActorContext_CalleeAsyncNonisolated()
370370
// CHECK-NEXT: // Isolation: global_actor. type: CustomActor
371-
await asyncInheritActorContextAcceptsSendingAsyncClosure { @CustomActor in } // expected-error {{global actor 'CustomActor'-isolated value of type '@CustomActor () async -> ()' passed as a strongly transferred parameter; later accesses could race}}
371+
await asyncInheritActorContextAcceptsSendingAsyncClosure { @CustomActor in }
372372

373373
// CHECK-LABEL: // closure #4 in test_CallerAsyncInheritsActorContext_CalleeAsyncNonisolated()
374374
// CHECK-NEXT: // Isolation: global_actor. type: MainActor
375-
await asyncInheritActorContextAcceptsSendingAsyncClosure { @MainActor in } // expected-error {{main actor-isolated value of type '@MainActor () async -> ()' passed as a strongly transferred parameter; later accesses could race}}
375+
await asyncInheritActorContextAcceptsSendingAsyncClosure { @MainActor in }
376376

377377
// CHECK-LABEL: // closure #5 in test_CallerAsyncInheritsActorContext_CalleeAsyncNonisolated()
378378
// CHECK-NEXT: // Isolation: global_actor. type: CustomActor
@@ -410,7 +410,7 @@ func test_CallerAsyncInheritsActorContext_CalleeAsyncMainActorIsolated() async {
410410

411411
// CHECK-LABEL: // closure #3 in test_CallerAsyncInheritsActorContext_CalleeAsyncMainActorIsolated()
412412
// CHECK-NEXT: // Isolation: global_actor. type: CustomActor
413-
await asyncInheritActorContextGlobalActorAcceptsSendingAsyncClosure { @CustomActor in } // expected-error {{global actor 'CustomActor'-isolated value of type '@CustomActor () async -> ()' passed as a strongly transferred parameter}}
413+
await asyncInheritActorContextGlobalActorAcceptsSendingAsyncClosure { @CustomActor in }
414414

415415
// CHECK-LABEL: // closure #4 in test_CallerAsyncInheritsActorContext_CalleeAsyncMainActorIsolated()
416416
// CHECK-NEXT: // Isolation: global_actor. type: MainActor

0 commit comments

Comments
 (0)