Global function could be quite confusing for old-school asynchrony. Something as innocent as queue hopping can already be surprising:
Task.unsafeCurrentTask // Task 1
DispatchQueue.main.async {
Task.unsafeCurrentTask // nil??
}
The same goes for just about any closure that escapes, which would be common here. It can also be hard to spot given that Swift's trailing closure is meant to mimic control-flow syntaxes.
I still think that having a checked Task instance would be the best approach. We need to freeze the Task (a.k.a suspend) for the Task instance to be valid so likely this goes hand-in-hand with task continuation (syntax TBD):
Task.isCancelled/local // 1
withContinuation { continuation, task in
task.isCancelled/local // same as 1
DispatchQueue.main.async {
task.isCancelled/local // same as 1
task.resume(...)
task.isCancelled/local // error
}
task.isCancelled/local // race
}
I think this could work with the current implementation without performance compromise. I could be wrong, though. ![]()
That should be a warning.
An
awaitoperand may also have no potential suspension points, which will result in a warning from the Swift compiler, following the precedent oftryexpressions: