a closure literal passed to initialize a Task that is instantiated within a function with an isolated parameter will currently only inherit the isolation of the enclosing function if the function's isolated parameter itself is strongly captured by the closure. in the given examples this is why commenting out the isolation assertions induces a data race (the closure is no longer isolated to the isolated actor parameter), and un-commenting them causes the isolation preconditions to succeed.
if you wish to avoid the capture's causing the closure to become isolated, you can currently exploit a shortcoming in the language, and capture the isolated parameter as a capture list item:
func isolatedSend1(
_ value: sending NonSendable,
isolated: isolated any Actor = #isolation
) {
isolated.preconditionIsolated() // â
Task { [isolated] in // explicit capture currently breaks isolation inheritance
isolated.preconditionIsolated() // đĨ
print("current value when reset: \(value.value)")
value.value = -1
}
}
in SE-420 these rules are stated as follows (emphasis mine):
According to SE-0304, closures passed directly to the
Taskinitializer (i.e.Task { /*here*/ }) inherit the statically-specified isolation of the current context if:
- the current context is non-isolated,
- the current context is isolated to a global actor, or
- the current context has an
isolatedparameter (including the implicitselfof an actor method) and that parameter is strongly captured by the closure.
this conditional isolation inheritance has been brought up numerous times as a confusing and non-obvious behavior (here is a similar discussion from a relatively recent thread), but the motivation is reasonable â changing the functionality to implicitly capture isolated parameters could introduce non-obvious memory leaks (and presumably would have to be a change staged-in over time to avoid altering the semantics of existing code).
however, regarding the lack of an expected diagnostic[1], i suspect this is a shortcoming with region-based isolation analysis, and would recommend filing a bug report if you can find the time to do so.
specifically in the first example there should presumably be a 'use after send' diagnostic produced âŠī¸