Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-15289] Empty dictionary unable to decode itself #57611

Closed
swift-ci opened this issue Oct 7, 2021 · 2 comments
Closed

[SR-15289] Empty dictionary unable to decode itself #57611

swift-ci opened this issue Oct 7, 2021 · 2 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 7, 2021

Previous ID SR-15289
Radar None
Original Reporter SDGGiesbrecht (JIRA User)
Type Bug
Environment

New to Swift 5.5, attested on Ubuntu, CentOS and Amazon Linux (and proven not present on macOS)

Additional Detail from JIRA
Votes 1
Component/s
Labels Bug
Assignee None
Priority Medium

md5: 0bbfd99264529883580e23a5166acfac

Issue Description:

For a key type that normally makes the dictionary encode as an array, empty instances end up encoded as empty dictionaries instead of empty arrays, leading to a type‐mismatch error when decoding.

struct Key: Codable, Hashable {
  var string: String
}
struct Value: Codable {
  var string: String
}
struct Context: Codable {
  var dictionary: [Key: Value] = [:]
}

let encoded = try JSONEncoder().encode([Context(dictionary: [Key(string: "..."): Value(string: "...")])])
print(String(data: encoded, encoding: .utf8))
// Optional("[{\"dictionary\":[{\"string\":\"...\"},{\"string\":\"...\"}]}]")
let decoded = try JSONDecoder().decode([Context].self, from: encoded)
print(decoded)
// ✓ Works just fine.

let emptyEncoded = try JSONEncoder().encode([Context()])
print(String(data: emptyEncoded, encoding: .utf8))
// Optional("[{\"dictionary\":{}}]")
let emptyDecoded = try JSONDecoder().decode([Context].self, from: emptyEncoded)
print(emptyDecoded)
// ✗ Throws: “typeMismatch(Swift.Array<Foundation.JSONValue>, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "dictionary", intValue: nil)], debugDescription: "Expected to decode Array<JSONValue> but found a dictionary instead.", underlyingError: nil))”

I haven’t figured out yet if the problem comes from the Codable conformance of Dictionary in the standard library, the Codable synthesis in the compiler, or just JSONEncoder in Foundation.

@swift-ci
Copy link
Collaborator Author

Comment by Jeremy David Giesbrecht (JIRA)

I just tested the above code on macOS and it does not suffer from the problem; only the Linux flavours exhibit the issue.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@SDGGiesbrecht
Copy link

SDGGiesbrecht commented Apr 30, 2022

Gone as of 5.6. (Also duplicate of apple/swift-corelibs-foundation#3180.)

Can be closed by whomever has the relevant permissions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

3 participants