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-5206] [Codable] The encoded results of Optional<URL>
are different between Container.encode (_: ...)
and Container.encodeIfPresent (_: ...)
.
#3846
Comments
@itaiferber Can you see this issue? |
Perhaps I think that this issue is caused by wrong usage of the API. |
Unfortunately, this is expected behavior that we can't do much about. This is a consequence of not yet having conditional conformance in Swift — the compiler has no static guarantee that This will be resolved when we have conditional conformance and can make that static assertion. |
Hmm. |
@norio-nomura That would work on |
Ah, I see. I didn't think about By the way, I filed a rdar://problem/32752900 as suggesting:
|
@norio-nomura Thanks! We've got a Radar tracking that internally — hopefully we'll be able to get that in an upcoming version of Xcode. |
Looks like there is actually a (small, non-scalable) workaround for this in the meantime, at least for |
@itaiferber How about following workaround? extension Decodable {
fileprivate init(from container: SingleValueDecodingContainer) throws {
self = try container.decode(Self.self)
}
}
extension Optional : Decodable /* where Wrapped : Decodable */ {
public init(from decoder: Decoder) throws {
// Initialize self here so we can get type(of: self).
self = .none
assertTypeIsDecodable(Wrapped.self, in: type(of: self))
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
let metaType = (Wrapped.self as! Decodable.Type)
let element = try metaType.init(from: container)
self = .some(element as! Wrapped)
}
}
} This would work with third party Decoders. |
@norio-nomura That looks... surprisingly reasonable. 🙂 I hadn't considered that, so thanks for pointing it out! I'll need to see how this plays with method dispatch (i.e. which overload of `SingleValueDecodingContainer.decode(_🙂` this will call for different types, or whether they'll always fall into the generic case). Unfortunately, we're past the deadline for the Swift 4.0 release for something like this, but this could be beneficial in an upcoming update. |
@norio-nomura This worked out surprisingly nicely, actually: PR-11315 |
@itaiferber I confirmed that this issue has been resolved on |
@norio-nomura Glad this resolved the issue, and thank you for the suggestion! Unfortunately, though, we're past the deadline on fixes for Swift 4.0 except for the most critical of bug fixes... This will make it to the next dot release, though. |
@itaiferber This issue seems to be critical for third party Encoders since it is hard to writing workaround code for third party Encoders. |
@itaiferber I would like to guard my tests by using {{#if swift()}} until this fix will be released. What version will this fix include? 4.0.1 or 4.1? |
I confirmed that this issue has been fixed on Xcode 9.2 beta (9C32c). 👍 |
@norio-nomura Thanks for confirming! 🙂 |
Environment
Xcode 9 beta 1
swift-4.0-DEVELOPMENT-SNAPSHOT-2017-06-11-a
Additional Detail from JIRA
md5: 0c154bae2e74b21f73dca582213bd87d
is duplicated by:
Issue Description:
This issue was founded at https://gist.github.com/ken0nek/4a84f5fb1d13e4201907ddcdcccc3cf1
Simplified version:
On implementing
Codable
conformance, if it usescontainer.encode(_:…)
instead ofcontainer.encodeIfPresent(_:…)
,container.encode(url, forKey: .url)
produces dictionary. But, `JSONDecoder` tries to decodeOptional<URL>
from string.This behavior is caused by https://github.com/itaiferber/swift/blob/a0f5c102aeef0c9812b5e7424ef5c3a880824b56/stdlib/public/core/Codable.swift#L3249
It should call
container.encode(_:)
instead of(wrapped as! Encodable).encode(to: encoder)
.The text was updated successfully, but these errors were encountered: