Skip to content

Commit 1a42c15

Browse files
committed
[Concurrency] Converting from nonisolated to @execution(caller) does not cross an isolation boundary
1 parent 45ca72e commit 1a42c15

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2734,7 +2734,16 @@ namespace {
27342734
// Converting to `@execution(caller)` function type
27352735
case FunctionTypeIsolation::Kind::NonIsolatedCaller: {
27362736
switch (fromIsolation.getKind()) {
2737-
case FunctionTypeIsolation::Kind::NonIsolated:
2737+
case FunctionTypeIsolation::Kind::NonIsolated: {
2738+
// nonisolated -> @execution(caller) doesn't cross
2739+
// an isolation boundary.
2740+
if (!fromFnType->isAsync())
2741+
break;
2742+
2743+
// @execution(concurrent) -> @execution(caller)
2744+
// crosses an isolation boundary.
2745+
LLVM_FALLTHROUGH;
2746+
}
27382747
case FunctionTypeIsolation::Kind::GlobalActor:
27392748
case FunctionTypeIsolation::Kind::Erased:
27402749
diagnoseNonSendableParametersAndResult(toFnType);

test/Concurrency/attr_execution_conversions.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,11 @@ func testNonSendableDiagnostics(
103103
let _: @execution(caller) () async -> NonSendable = erased2 // expected-note {{type 'NonSendable' does not conform to 'Sendable' protocol}}
104104
// expected-error@-1 {{cannot convert '@isolated(any) @Sendable () async -> NonSendable' to '@execution(caller) () async -> NonSendable' because crossing of an isolation boundary requires parameter and result types to conform to 'Sendable' protocol}}
105105

106-
let _: @execution(caller) (NonSendable) async -> Void = nonIsolated1 // expected-note {{type 'NonSendable' does not conform to 'Sendable' protocol}}
107-
// expected-error@-1 {{annot convert '@Sendable (NonSendable) -> Void' to '@execution(caller) (NonSendable) async -> Void' because crossing of an isolation boundary requires parameter and result types to conform to 'Sendable' protocol}}
106+
let _: @execution(caller) (NonSendable) async -> Void = nonIsolated1 // Ok
108107
let _: @execution(caller) (NonSendable) async -> Void = nonIsolated2 // expected-note {{type 'NonSendable' does not conform to 'Sendable' protocol}}
109108
// expected-error@-1 {{cannot convert '@Sendable (NonSendable) async -> Void' to '@execution(caller) (NonSendable) async -> Void' because crossing of an isolation boundary requires parameter and result types to conform to 'Sendable' protocol}}
110109

111-
let _: @execution(caller) () async -> NonSendable = nonIsolated3 // expected-note {{type 'NonSendable' does not conform to 'Sendable' protocol}}
112-
// expected-error@-1 {{cannot convert '@Sendable () -> NonSendable' to '@execution(caller) () async -> NonSendable' because crossing of an isolation boundary requires parameter and result types to conform to 'Sendable' protocol}}
110+
let _: @execution(caller) () async -> NonSendable = nonIsolated3 // Ok
113111
let _: @execution(caller) () async -> NonSendable = nonIsolated4 // expected-note {{type 'NonSendable' does not conform to 'Sendable' protocol}}
114112
// expected-error@-1 {{cannot convert '@Sendable () async -> NonSendable' to '@execution(caller) () async -> NonSendable' because crossing of an isolation boundary requires parameter and result types to conform to 'Sendable' protocol}}
115113

0 commit comments

Comments
 (0)