I think using MainActor.assumeIsolated would be fine if there were some way that I could restrict the type from leaving the @MainActor concurrency context. For example, with the following implementation:
struct ThingCollection: RandomAccessCollection {
let store: Store
@MainActor init(store: Store) { // constrained to main actor
self.store = store
}
subscript(position: Int) -> Store.Thing {
MainActor.assumeIsolated { store.item(at: position) }
}
// etc...
}
It's still possible to break strict concurrency guarantees:
func makeThing() async {
let store = Store()
let collection = await ThingCollection(store: store)
print(collection[0]) // ❌ uh-oh, we're not on the main actor. Assertion failure.
}
However, if we had something like a `noasync' we could effectively prevent a type from leaving the targeted isolation context:
struct ThingCollection: RandomAccessCollection {
@MainActor init(store: Store) noasync { // can only be called synchronously from the main actor
self.store = store
}
// etc...
}
If I'm understanding the implications of the semantics, assuming all the initialisers of the type followed the same format, and assuming the type remained non-Sendable, this would allow us to express a type that can conform to a non-isolated protocol, while still being safely restricted to a chosen isolation context by the compiler.
func makeThing() async {
let store = Store()
let collection = await ThingCollection(store: store) // ❌ ERROR: ThingCollection can't be instantiated in the current isolation context
}
Basically, I'm trying to find a safe way to access all the non-isolated protocols for types with actor-isolated dependencies.
EDIT: Maybe you could also make a whole type noasync with something like @MainActor(noasync) struct ThingCollection: RandomAccessCollection { ... } that would do the same as above, but also prevents adding Sendable conformance, and negate the need for calls to MainActor.assumeIsolated as, by definition, the whole type is synchronous to the MainActor.
EDIT 2: Nevermind, clearly I've been too liberal with my @MainActor annotations!