So the signature in the proposal is specifically about the original pitched idea here: the "don't ever allow not synchronous execution", which is now being considered to change into "try to run synchronously". I was working out yesterday what the signature will have to become, and it seems it would be as follows:
@_implicitSelfCapture _ operation: __owned sending @isolated(any) @escaping () async throws -> Success
(which uncovered a but in interface printing, so we're working to fix that, while at it). We're not relying on the @_inheritActorContext here, but on comparing executor of current and target and doing the synchronous run if able to.
In practice this would be these specific situations where we definitely change isolation:
@SomeActor
func test() {
Task.<immediately?> { @OtherActor in } // always enqueues
}
actor X {
func test() {
Task.<immediately?> { @OtherActor in } // always enqueues
}
}
Here we statically know these must enqueue and won't be "immediate" / "start synchronous" ever. So I guess we could warn about it... I would not want to warn about situations where we're not 100% certain.
There's two parts to talk about here:
One is that we can actually "start synchronously if not actually closed over any specific isolation" but it's a bit of an implementation hack:
Basically, if we use @isolated(any) and the closure is not isolated, its executor will be generic, then we check if the "target" isolation is generic, and if so, we just start synchronously immediately on the caller thread. The subsequent isolation / executor of that closure though, e.g. after we suspend and resume would be the generic executor then though. So we'd have the same semantics as Task{} but we would manage to start synchronously anyway. It's a bit of a hack since we interpret the "no specific isolation" as "ok to start on caller", but given that there's no way to enforce a closure to be nonisolated this actually kinda works I think.
I worked that out yesterday actually - you can check the impl here (pending a bug in sending checking).
The second topic is if that "forgot to close over isolated value / actor so therefore suddenly we execute on the global pool" is reasonable or not. Personally, I see a lot of people struggling with this and I'm more than sure that most developers don't realize this is the rule at all, so I'd love to fix it not only here but also for Task{} that "when created from context that is isolated, inherit that isolation".
IMHO, an ideal outcome would be that Task{} and this API would consistently just inherit the enclosing isolation and we'd be better off with less confusing language rule here overall.