Can non-Sendable types be captured in Tasks?

Right now, I guess that the following code should occur any errors.

class SomeClass {
    var count: Int
    init(count: Int) {
        self.count = count
    }
}

let someClass = SomeClass(count: 0)

//public init(priority: TaskPriority? = nil, operation: @escaping @Sendable () async -> Success)
Task {
    someClass.count += 1
}

//public init(priority: TaskPriority? = nil, operation: @escaping @Sendable () async -> Success)
Task {
    someClass.count += 1
}

But, in Swift(version 5.8), this code snippet could get compiled. In Swift6, does this code snippet occur any errors?

In Swift v.Future, the global someClass will have to be isolated to a global actor, so the line someClass.count += 1 will require either:

  1. That the entire Task closure is isolated to the same global actor, or
  2. That you switch to the appropriate global actor for that operation
    (e.g. await MainActor.run { someClass.count += 1 }).

Future directions

Restricting global and static variables

A global actor annotation on a global or static variable synchronizes all access to that variable through that global actor. We could require that all mutable global and static variables be annotated with a global actor, thereby eliminating those as a source of data races. Specifically, we can require that every global or static variable do one of the following:

  • Explicitly state that it is part of a global actor, or
  • Be immutable (introduced via let), non-isolated, and of Sendable type.

This allows global/static immutable constants to be used freely from any code, while any data that is mutable (or could become mutable in a future version of a library) must be protected by an actor. However, it comes with significant source breakage: every global variable that exists today would require annotation. Therefore, we aren't proposing to introduce this requirement, and instead leave the general data-race safety of global and static variables to a later proposal.

SE-0316: Global Actors

It is difficult to say with any precision what will/will not be an error in Swift 6. There are a few compiler flags you can use to try things, but they're inconsistent.