Skip to content

Commit 5be5bf2

Browse files
committed
refactor and update tests per PR feedback
1 parent 6711957 commit 5be5bf2

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5031,6 +5031,10 @@ ERROR(capture_across_type_decl,none,
50315031
"scope",
50325032
(const NominalTypeDecl *, const ValueDecl *))
50335033

5034+
ERROR(isolated_any_conversion_to_synchronous_func,none,
5035+
"converting @isolated(any) function of type %0 to synchronous function type %1 is not allowed",
5036+
(Type, Type))
5037+
50345038
ERROR(reference_to_invalid_decl,none,
50355039
"cannot reference invalid declaration %0", (const ValueDecl *))
50365040

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,11 +2943,6 @@ ConstraintSystem::matchFunctionIsolations(FunctionType *func1,
29432943
ConstraintLocatorBuilder locator) {
29442944
auto isolation1 = func1->getIsolation(), isolation2 = func2->getIsolation();
29452945

2946-
// An @isolated(any) function cannot be converted to a non-@isolated(any)
2947-
// synchronous function regardless of whether or not it is itself async.
2948-
if (isolation1.isErased() && !isolation2.isErased() && !func2->isAsync())
2949-
return false;
2950-
29512946
// If we have a difference in isolation kind, we need a conversion.
29522947
// Make sure that we're looking for a conversion, and increase the
29532948
// function-conversion score to make sure this solution is worse than

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2703,6 +2703,18 @@ namespace {
27032703
}
27042704
}
27052705

2706+
// @isolated(any) functions (async or not) cannot be converted to
2707+
// non-@isolated(any) synchronous functions.
2708+
if (fromIsolation.isErased() && !toIsolation.isErased() &&
2709+
!toFnType->isAsync()) {
2710+
ctx.Diags
2711+
.diagnose(funcConv->getLoc(),
2712+
diag::isolated_any_conversion_to_synchronous_func,
2713+
fromFnType, toFnType)
2714+
.warnUntilSwiftVersion(7);
2715+
return;
2716+
}
2717+
27062718
// Conversions from non-Sendable types are handled by
27072719
// region-based isolation.
27082720
// Function conversions are used to inject concurrency attributes

test/Concurrency/isolated_any.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,16 @@ func testConvertIsolatedAnyToNonIsolated(fn: @Sendable @isolated(any) () -> ())
7171

7272
func requireSendableNonIsolated_sync(_ fn: @Sendable () -> ()) {}
7373
func testConvertIsolatedAnyToNonIsolated_sync(fn: @Sendable @isolated(any) () -> ()) {
74-
// expected-error @+1 {{cannot convert value of type '@isolated(any) @Sendable () -> ()' to expected argument type '@Sendable () -> ()}}
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}}
7575
requireSendableNonIsolated_sync(fn)
7676
}
7777

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+
7884
func requireSendableGlobalActor(_ fn: @Sendable @MainActor () -> ()) {}
7985
func testConvertIsolatedAnyToMainActor(fn: @Sendable @isolated(any) () -> ()) {
8086
// expected-error @+1 {{cannot convert value of type '@isolated(any) @Sendable () -> ()' to expected argument type '@MainActor @Sendable () -> ()'}}
@@ -131,8 +137,22 @@ func testFunctionIsolationExprTuple(
131137
return (fn1?.isolation, fn2?.isolation)
132138
}
133139

134-
func nonSendableIsolatedAny(
140+
func nonSendableIsolatedAnySyncToSendableSync(
135141
_ fn: @escaping @isolated(any) () -> Void // expected-note {{parameter 'fn' is implicitly non-sendable}}
136142
) {
137143
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}}
138158
}

0 commit comments

Comments
 (0)