Skip to content

Commit a45fb51

Browse files
committed
[Sema]: ban @isolated(any) conversions to synchronous function types
1 parent 99afbc1 commit a45fb51

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5023,6 +5023,9 @@ NOTE(add_explicit_escaping,none,
50235023
"add explicit @escaping to function parameter #%0",
50245024
(unsigned))
50255025

5026+
ERROR(converting_func_loses_isolation,none,
5027+
"converting function value of type %0 to %1 loses isolation",
5028+
(Type, Type))
50265029
ERROR(converting_func_loses_global_actor,none,
50275030
"converting function value of type %0 to %1 loses global actor %2",
50285031
(Type, Type, Type))

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2985,6 +2985,10 @@ ConstraintSystem::matchFunctionIsolations(FunctionType *func1,
29852985
case FunctionTypeIsolation::Kind::Erased:
29862986
return matchIfConversion();
29872987

2988+
// TODO: should this be handled here?
2989+
// case FunctionTypeIsolation::Kind::Erased:
2990+
// return func2->isAsync() && matchIfConversion();
2991+
29882992
// Parameter isolation is value-dependent and cannot be erased.
29892993
case FunctionTypeIsolation::Kind::Parameter:
29902994
return false;

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,14 @@ namespace {
27112711
if (!fromFnType->isSendable())
27122712
return;
27132713

2714+
// @isolated(any) cannot be converted to a synchronous function type
2715+
if (fromIsolation.isErased() && !toFnType->isAsync()) {
2716+
ctx.Diags.diagnose(funcConv->getLoc(),
2717+
diag::converting_func_loses_isolation,
2718+
fromFnType, toFnType);
2719+
return;
2720+
}
2721+
27142722
switch (toIsolation.getKind()) {
27152723
// Converting to `@execution(caller)` function type
27162724
case FunctionTypeIsolation::Kind::NonIsolatedCaller: {

test/Concurrency/isolated_any.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,17 @@ 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-error @+1 {{converting function value of type '@isolated(any) @Sendable () -> ()' to '@Sendable () -> ()' loses isolation}}
75+
requireSendableNonIsolated_sync(fn)
76+
}
77+
7278
func requireSendableGlobalActor(_ fn: @Sendable @MainActor () -> ()) {}
7379
func testConvertIsolatedAnyToMainActor(fn: @Sendable @isolated(any) () -> ()) {
7480
// expected-error @+1 {{cannot convert value of type '@isolated(any) @Sendable () -> ()' to expected argument type '@MainActor @Sendable () -> ()'}}

0 commit comments

Comments
 (0)