Skip to content

Commit b684e71

Browse files
authored
Merge pull request #81275 from jamieQ/invalid-isolated-any-conversion-6.2
[6.2][Sema]: ban @isolated(any) conversions to synchronous function types
2 parents 297494f + 89b98a2 commit b684e71

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5024,6 +5024,10 @@ ERROR(capture_across_type_decl,none,
50245024
"%0 declaration cannot close over value %1 defined in outer scope",
50255025
(DescriptiveDeclKind, Identifier))
50265026

5027+
ERROR(isolated_any_conversion_to_synchronous_func,none,
5028+
"converting @isolated(any) function of type %0 to synchronous function type %1 is not allowed",
5029+
(Type, Type))
5030+
50275031
ERROR(reference_to_invalid_decl,none,
50285032
"cannot reference invalid declaration %0", (const ValueDecl *))
50295033

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2710,6 +2710,18 @@ namespace {
27102710
}
27112711
}
27122712

2713+
// @isolated(any) functions (async or not) cannot be converted to
2714+
// synchronous, non-@isolated(any) functions.
2715+
if (fromIsolation.isErased() && !toIsolation.isErased() &&
2716+
!toFnType->isAsync()) {
2717+
ctx.Diags
2718+
.diagnose(funcConv->getLoc(),
2719+
diag::isolated_any_conversion_to_synchronous_func,
2720+
fromFnType, toFnType)
2721+
.warnUntilFutureSwiftVersion();
2722+
return;
2723+
}
2724+
27132725
// Conversions from non-Sendable types are handled by
27142726
// region-based isolation.
27152727
// Function conversions are used to inject concurrency attributes

test/Concurrency/isolated_any.swift

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,23 @@ func testEraseFromIsolatedArgument() {
6464
requireIsolatedAnyWithActorArgument(hasIsolatedArgument)
6565
}
6666

67-
func requireSendableNonIsolated(_ fn: @Sendable () -> ()) {}
67+
func requireSendableNonIsolated(_ fn: @Sendable () async -> ()) {}
6868
func testConvertIsolatedAnyToNonIsolated(fn: @Sendable @isolated(any) () -> ()) {
6969
requireSendableNonIsolated(fn)
7070
}
7171

72+
func requireSendableNonIsolated_sync(_ fn: @Sendable () -> ()) {}
73+
func testConvertIsolatedAnyToNonIsolated_sync(fn: @Sendable @isolated(any) () -> ()) {
74+
// expected-warning @+1 {{converting @isolated(any) function of type '@isolated(any) @Sendable () -> ()' to synchronous function type '@Sendable () -> ()' is not allowed; this will be an error in a future Swift language mode}}
75+
requireSendableNonIsolated_sync(fn)
76+
}
77+
78+
func requireNonSendableNonIsolated_sync(_ fn: () -> ()) {}
79+
func testConvertIsolatedAnyToNonSendableNonIsolated_sync(fn: @isolated(any) () -> ()) {
80+
// expected-warning @+1 {{converting @isolated(any) function of type '@isolated(any) () -> ()' to synchronous function type '() -> ()' is not allowed; this will be an error in a future Swift language mode}}
81+
requireNonSendableNonIsolated_sync(fn)
82+
}
83+
7284
func requireSendableGlobalActor(_ fn: @Sendable @MainActor () -> ()) {}
7385
func testConvertIsolatedAnyToMainActor(fn: @Sendable @isolated(any) () -> ()) {
7486
// expected-error @+1 {{cannot convert value of type '@isolated(any) @Sendable () -> ()' to expected argument type '@MainActor @Sendable () -> ()'}}
@@ -125,8 +137,22 @@ func testFunctionIsolationExprTuple(
125137
return (fn1?.isolation, fn2?.isolation)
126138
}
127139

128-
func nonSendableIsolatedAny(
140+
func nonSendableIsolatedAnySyncToSendableSync(
129141
_ fn: @escaping @isolated(any) () -> Void // expected-note {{parameter 'fn' is implicitly non-sendable}}
130142
) {
131143
let _: @Sendable () -> Void = fn // expected-warning {{using non-sendable parameter 'fn' in a context expecting a '@Sendable' closure}}
144+
// expected-warning @-1 {{converting @isolated(any) function of type '@isolated(any) () -> Void' to synchronous function type '@Sendable () -> Void' is not allowed; this will be an error in a future Swift language mode}}
145+
}
146+
147+
func nonSendableIsolatedAnyAsyncToSendableSync(
148+
_ fn: @escaping @isolated(any) () async -> Void // expected-note {{parameter 'fn' is implicitly non-sendable}}
149+
) {
150+
let _: @Sendable () -> Void = fn // expected-warning {{using non-sendable parameter 'fn' in a context expecting a '@Sendable' closure}}
151+
// expected-error @-1 {{invalid conversion from 'async' function of type '@isolated(any) () async -> Void' to synchronous function type '@Sendable () -> Void'}}
152+
}
153+
154+
func nonSendableIsolatedAnyAsyncToSendableAsync(
155+
_ fn: @escaping @isolated(any) () async -> Void // expected-note {{parameter 'fn' is implicitly non-sendable}}
156+
) {
157+
let _: @Sendable () async -> Void = fn // expected-warning {{using non-sendable parameter 'fn' in a context expecting a '@Sendable' closure}}
132158
}

0 commit comments

Comments
 (0)