You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[sema] Work around a double curry thunk actor isolation inference bug that is a knock on effect of ced96aa.
Specifically, there is currently a bug in TypeCheckConcurrency.cpp where we do
not visit autoclosures. This causes us to never set the autoclosure's
ActorIsolation field like all other closures. For a long time we were able to
get away with this just by relying on the isolation of the decl context of the
autoclosure... but with the introduction of nonisolated(nonsending), we found
cases where the generated single curry autoclosure would necessarily be
different than its decl context (e.x.: a synchronous outer curry thunk that is
nonisolated that returns an inner curry thunk that is
nonisolated(nonsending)). This problem caused us to hit asserts later in the
compiler since the inner closure was actually nonisolated(nonsending), but we
were thinking that it should have been concurrent.
To work around this problem, I changed the type checker in
ced96aa to explicitly set the isolation of
single curry thunk autoclosures when it generates them. The reason why we did
this is that it made it so that we did not have to have a potential large source
break in 6.2 by changing TypeCheckConcurrency.cpp to visit all autoclosures it
has not been visiting.
This caused a follow on issue where since we were now inferring the inner
autoclosure to have the correct isolation, in cases where we were creating a
double curry thunk for an access to a global actor isolated field of a
non-Sendable non-global actor isolated nominal type, we would have the outer
curry thunk have unspecified isolation instead of main actor isolation. An
example of this is the following:
```swift
class A {
var block: @mainactor () -> Void = {}
}
class B {
let a = A()
func d() {
a.block = c // Error! Passing task isolated 'self' to @mainactor closure.
}
@mainactor
func c() {}
}
```
This was unintentional. To work around this, this commit changes the type
checker to explicitly set the double curry thunk isolation to the correct value
when the type checker generates the double curry thunk in the same manner as it
does for single curry thunks and validates that if we do set the value to
something explicitly that it has the same value as the single curry thunk.
rdar://152522631
a.block = c // expected-warning {{converting non-Sendable function value to '@MainActor @Sendable () -> Void' may introduce data races}}
2087
-
// expected-tns-warning @-1 {{sending 'self' risks causing data races}}
2088
-
// expected-tns-note @-2 {{task-isolated 'self' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
2087
+
// expected-tns-warning @-1 {{non-Sendable '@MainActor () -> ()'-typed result can not be returned from main actor-isolated function to nonisolated context}}
2088
+
// expected-tns-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
2089
+
// expected-tns-warning @-3 {{sending 'self' risks causing data races}}
2090
+
// expected-tns-note @-4 {{task-isolated 'self' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
a.block = c // expected-warning {{converting non-Sendable function value to '@MainActor @Sendable () -> Void' may introduce data races}}
352
+
// expected-warning @-1 {{non-Sendable '@MainActor () -> ()'-typed result can not be returned from main actor-isolated function to global actor 'CustomActor'-isolated context}}
353
+
// expected-note @-2 {{a function type must be marked '@Sendable' to conform to 'Sendable'}}
0 commit comments