The following behavior seems inconsistent or incomplete to me. Suppose we have a static reference-type property, where the type is associated with an actor isolation context. To make this concrete, here are 3 similar possibilities:
@MainActor class Assignee {
static var currentAssignee: Assignee?
var name: String
…
}
class AssigneeToo {
static var currentAssignee: Assignee?
@MainActor var name: String
…
}
actor AssigneeTri {
static var currentAssignee: Assignee?
var name: String
…
}
In all 3 cases, access to the type's mutable instance state (e.g. name
property) is isolated. Now consider the static property, and let's try some non-isolated accesses from somewhere else:
print(String(describing: Assignee.currentAssignee))
// ^^ Static property 'currentAssignee' isolated to global actor 'MainActor'
// can not be referenced from this synchronous context
print(String(describing: AssigneeToo.currentAssignee))
print(String(describing: AssigneeTri.currentAssignee))
The 2nd and 3rd examples are fine, because the currentAssignee
property is non-isolated by default. The error message on the first example is also correct, because the property is isolated.
The problem is that there's apparently no way to declare the static property nonisolated
in type Assignee
. It has defaulted to isolated because of the class-level @MainActor
annotation.
However, the examples with AssigneeToo
and AssigneeTri
demonstrate that an instance's isolation "bubble" isn't necessary for static properties. Isolation of a static property is orthogonal to instance-level isolation.
It would seem, therefore, that in the Assignee
case, it should be possible to mark the static property nonisolated
, but this doesn't work:
nonisolated static var currentAssignee: Assignee?
// ^^ Nonisolated' can not be applied to stored properties
Is there some reason why this should be disallowed?
It comes down to a source-code ergonomics issue. I can certainly remove the global actor annotation from Assignee
and apply it only to the declarations I want to be isolated — in other words, construct the class like AssigneeToo
rather than Assignee
— but this is painful to do and ugly to read if there are a lot of declarations in the type.
** Also, there's a tiny typo in that error message, it seems. It should be 'nonisolated'
, rather than Nonisolated'
, shouldn't it?