There was a lot of discussion on the original pitch that helped shape the proposal. Feedback during the proposal review was comparatively light, but it was positive. A question came up about the proposal's design for suppressing the Sendable conformance in global-actor-isolated subclasses of non-Sendable classes. The Language Steering Group decided to accept SE-0434 as written but requested a paragraph in Alternatives Considered clarifying the design decision, which held up announcing the acceptance.
As always, I'd like to thank everyone who read and commented on this proposal at any stage for participating in Swift Evolution; this is how we make the language better.
I know I've missed the boat on this one, but one thing I've found myself wanting to express recently is a non-sendable GAIT that can then 'assume' its non-isolated members are, in fact, isolated to a global actor.
Take the example of a GAIT that acts as a data store:
@MainActor final class IsolatedStore {
var numberOfItems: Int { /* implementation omitted */ }
func item(at index: Int) -> Item { /* implementation omitted */ }
}
A type of this shape could benefit from conforming to RandomAccessCollection, but attempting to conform this type will of course result in warnings about accessing an actor-isolated member from a non-isolated context:
extension Store: RandomAccessCollection {
nonisolated var startIndex: Int { 0 }
// ❌ Main actor-isolated property 'numberOfItems' can not be referenced from a non-isolated context
nonisolated var endIndex: Int { numberOfItems + 1 }
nonisolated func index(after i: Int) -> Int { i + 1 }
// ❌ Call to main actor-isolated instance method 'item(at:)' in a synchronous nonisolated context
nonisolated subscript(position: Int) -> Item { item(at: position) }
}
But if we had some way to express that a GAIT was non-Sendable then – if I understand the concurrency model correctly – we could guarantee that any non-isolated call is, in fact, isolated to the global actor.
@MainActor final class IsolatedStore: ~Sendable, RandomAccessCollection {
var numberOfItems: Int { /* implementation omitted */ }
func item(at index: Int) -> Item { /* implementation omitted */ }
// Could we implicitly 'assume isolated' to the global actor here?
nonisolated var startIndex: Int { 0 }
nonisolated var endIndex: Int { numberOfItems + 1 } ✅
nonisolated func index(after i: Int) -> Int { i + 1 }
nonisolated subscript(position: Int) -> Item { item(at: position) } ✅
}
Maybe this would mean nonisolated could be inferred, also. Would be interesting to hear if this could be feasible. Would be useful to get protocol conformance available more widely for GAITs.
EDIT: Cancel that, I'm beginning to see the error of my ways. Clearly I've been too liberal with my @MainActor annotations!