-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Open
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labelsThis issue needs more specific labels
Description
Description
If an Encodable is wrapped up as a value in a dictionary, and you encode the dictionary with PropertyListEncoder in a background actor, the app crashes with the curious claim: "Could not cast value of type Whatever to 'Swift.Encodable', even though the type Whatever is clearly marked as Encodable.
Reproduction
import Foundation
struct Thing: Codable {
let name: String
}
actor ActorWhoEncodes {
var dict = [String: Thing]()
func encode(thing: Thing) throws -> Data? {
dict["testing"] = thing
return try PropertyListEncoder().encode(dict)
}
}And then, elsewhere, something of this sort (run on the main actor):
Task {
try await ActorWhoEncodes().encode(thing: Thing(name: "matt"))
// Crash! Could not cast value of type 'PropertyListEncoderTest.Thing'
// to 'Swift.Encodable'
}Expected behavior
Either we should not crash or we should not have compiled in the first place.
Environment
swift-driver version: 1.127.14.1 Apple Swift version 6.2.1 (swiftlang-6.2.1.4.8 clang-1700.4.4.1)
Target: arm64-apple-macosx26.0
Additional information
Ultimately I found a workaround! Namely, conform nonisolated to Codable:
struct Thing: nonisolated Codable {
So, whether there is a bug here and what the bug is, I leave to you. I can think of three possible responses:
- No bug. This is all expected and is what you get for not saying
nonisolated Codablein the first place, if you were thinking of using PropertyListEncoder in an actor. - The bug is the failure of the compiler to call out the problem. It's interesting that if you tell the PropertyListEncoder to
encode(thing), you get a helpful compiler error: "Main actor-isolated conformance of 'Thing' to 'Encodable' cannot be used in actor-isolated context". Thus, one might argue that the real trouble here is that when what we encode is a Thing wrapped in a Dictionary, there is no compile-time error. However, it may be that the compiler just doesn't have the cojones to think as deep as it would need to in order to notice the issue. - It's a bug (and perhaps is just a sign of issues with using PropertyListEncoder under Swift concurrency; it wouldn't be the first time someone has pointed that out).
Metadata
Metadata
Assignees
Labels
bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labelsThis issue needs more specific labels