If trying to make var
declared on actor
nonisolated
, Swift 6 compiler of course produces error:
"'nonisolated' cannot be applied to mutable stored properties".
That is clear because such declaration would create shared mutable state which Swift 6 doesn't allow.
However for some reason it allows such kind of declaration if variable is lazy
. The following code compiles and runs with Swift 6 compiler:
actor A {
var i = 0
nonisolated lazy var k = 0
nonisolated func readK() -> Int {
k += 1
return k
}
}
lazy
affects only how variable is initialized, however following mutations behave the same as if it would be declared nonisolated var k = 0
, which is not allowed by the compiler.
This effectively leads to possibility to create following code, which is explicit data race:
func run() {
let a = A()
Task.detached {
let result = a.readK()
print("\(result)")
}
Task.detached {
let result = a.readK()
print("\(result)")
}
}
I've ran this code and indeed it creates data race leading to "1" printed by both tasks.
To me this looks like a bug in the compiler and should not be allowed. Or am I missing something?