If a MainActor isolated type is marked as Encodable, the automatically generated implementation of the Decodable protocol does not play well with @preconcurrency.
I would expect this to compile:
@MainActor
struct MyStruct : @preconcurrency Encodable {
var myString = "123"
}
But compiling this fails with the following error:
Main actor-isolated property 'myString' can not be referenced from a non-isolated context
We found out that the reason for this is the "nonisolated" keyword which the implicitly generated Encodable implementation includes, like this:
@MainActor
struct MyStruct : @preconcurrency Encodable {
var myString = "123"
private enum CodingKeys: CodingKey {
case myString
}
nonisolated func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.myString, forKey: .myString)
}
}
If I explicitly implement Encodable like this without "nonisolated", the error disappears:
@MainActor
struct MyStruct : @preconcurrency Encodable {
var myString = "123"
private enum CodingKeys: CodingKey {
case myString
}
func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.myString, forKey: .myString)
}
}