Skip to content

Commit 33a39e4

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.
1 parent 3e43b34 commit 33a39e4

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
@@ -1154,6 +1154,28 @@ struct PartitionOpEvaluator {
11541154
}
11551155

11561156
private:
1157+
bool isConvertFunctionFromSendableType(SILValue equivalenceClassRep) const {
1158+
SILValue valueToTest = equivalenceClassRep;
1159+
while (true) {
1160+
if (auto *i = dyn_cast<ThinToThickFunctionInst>(valueToTest)) {
1161+
valueToTest = i->getOperand();
1162+
continue;
1163+
}
1164+
if (auto *i = dyn_cast<ConvertEscapeToNoEscapeInst>(valueToTest)) {
1165+
valueToTest = i->getOperand();
1166+
continue;
1167+
}
1168+
break;
1169+
}
1170+
1171+
auto *cvi = dyn_cast<ConvertFunctionInst>(valueToTest);
1172+
if (!cvi)
1173+
return false;
1174+
1175+
return cvi->getOperand()->getType().isSendable(
1176+
equivalenceClassRep->getFunction());
1177+
}
1178+
11571179
// Private helper that squelches the error if our transfer instruction and our
11581180
// use have the same isolation.
11591181
void handleLocalUseAfterTransferHelper(const PartitionOp &op, Element elt,
@@ -1166,12 +1188,13 @@ struct PartitionOpEvaluator {
11661188
return;
11671189
}
11681190

1169-
// If we have a temporary that is initialized with an unsafe nonisolated
1170-
// value... squelch the error like if we were that value.
1171-
//
1172-
// TODO: This goes away with opaque values.
11731191
if (SILValue equivalenceClassRep =
11741192
getRepresentative(transferringOp->get())) {
1193+
1194+
// If we have a temporary that is initialized with an unsafe nonisolated
1195+
// value... squelch the error like if we were that value.
1196+
//
1197+
// TODO: This goes away with opaque values.
11751198
if (auto *asi = dyn_cast<AllocStackInst>(equivalenceClassRep)) {
11761199
if (SILValue value = getInitOfTemporaryAllocStack(asi)) {
11771200
if (auto elt = getElement(value)) {
@@ -1182,6 +1205,11 @@ struct PartitionOpEvaluator {
11821205
}
11831206
}
11841207
}
1208+
1209+
// See if we have a convert function from a `@Sendable` type. In this
1210+
// case, we want to squelch the error.
1211+
if (isConvertFunctionFromSendableType(equivalenceClassRep))
1212+
return;
11851213
}
11861214

11871215
// If our instruction does not have any isolation info associated with it,
@@ -1206,12 +1234,12 @@ struct PartitionOpEvaluator {
12061234
const PartitionOp &op, Element elt,
12071235
SILDynamicMergedIsolationInfo dynamicMergedIsolationInfo) const {
12081236
if (shouldTryToSquelchErrors()) {
1209-
// If we have a temporary that is initialized with an unsafe nonisolated
1210-
// value... squelch the error like if we were that value.
1211-
//
1212-
// TODO: This goes away with opaque values.
12131237
if (SILValue equivalenceClassRep =
12141238
getRepresentative(op.getSourceOp()->get())) {
1239+
// If we have a temporary that is initialized with an unsafe nonisolated
1240+
// value... squelch the error like if we were that value.
1241+
//
1242+
// TODO: This goes away with opaque values.
12151243
if (auto *asi = dyn_cast<AllocStackInst>(equivalenceClassRep)) {
12161244
if (SILValue value = getInitOfTemporaryAllocStack(asi)) {
12171245
if (auto elt = getElement(value)) {
@@ -1222,6 +1250,11 @@ struct PartitionOpEvaluator {
12221250
}
12231251
}
12241252
}
1253+
1254+
// See if we have a convert function from a `@Sendable` type. In this
1255+
// case, we want to squelch the error.
1256+
if (isConvertFunctionFromSendableType(equivalenceClassRep))
1257+
return;
12251258
}
12261259
}
12271260

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)