Open krzyzanowskim opened 6 years ago
I don't think you can redefine the RawValue
associated type like that—Foo
gets imported as RawRepresentable
with String
as its RawValue
. The following code compiles for me:
extension Foo : Codable {
public init(from decoder: Decoder) throws {
let unkeyedContainer = try decoder.singleValueContainer()
self.init(try unkeyedContainer.decode(RawValue.self))
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.rawValue)
}
}
You know what, I totally misread—you're talking about expecting Foo
to be codable so that you can use it as the key in a codable dictionary.
That behavior has changed—in Swift 4.0 all dictionaries were "codable," but would fail at runtime if the keys weren't actually codable. In Swift 4.1 we have conditional conformance, so now only dictionaries with codable keys are themselves codable. It looks like that's what you're running into.
(It would make sense to me that enums imported from Objective-C would automatically be Codable, but I don't know if that's a regression from Swift 4.0 or not.)
Yea, totaly. I thing it could be codable for basic types.
also it shouldn't compile to you too as there is Any type in the dictionary.
Thanks, Marcin. The code you wrote can't have worked in Swift 4.0, because Any
can't be decoded (even though that wasn't statically enforced). Can you find an example that actually did decode, so we know what we're looking for?
cc @itaiferber
@itaiferber: Currently a very limited set of protocols are mirrored over on NS_TYPED_EXTENSIBLE_ENUM wrappers – Equatable, Hashable, and ObjectiveCBridgeable. Should Codable be included as well?
@natecook1000 my fault, I extracted it from the code. right, for such type, I can't redefine the RawValue that way.
@belkadan I guess it never worked at runtime, just compiles. It'd be nice if it actually works automatically for basic types.
there is another though
```
@protocol Pro \<NSObject>
@end
```
```
extension protocol Pro: Codable {}
```
the code compiles, but I believe it shouldn't unless there is some magic.
@belkadan Potentially — I could see this being useful. However, other RawRepresentable
types don't automatically get Codable
conformance, so that'd be a bit magic. It's also relatively easy to create NS_TYPED_EXTENSIBLE_ENUM
values which couldn't be Codable
, so we'd need to be wary of that.
@krzyzanowskim That code shouldn't compile — protocols can't be extended with conformance to other protocols. (Besides the syntax error of writing extension protocol
.) Is that also in Swift 4.0.3? Doesn't work for me (correctly) in Swift 4.1
@itaiferber after deleting DerivedData it doesn't compile anymore (ufff) and presents the syntax error. Sorry about that, I was very confused.
@krzyzanowskim That's alright — happens all the time. 🙂 In any case, about this issue specifically: I think we need to figure out a better way to make RawRepresentable
things Codable
by default. We have default implementations for primitive types, but you'd still have to write extension MyImportedEnum : Codable
in order to benefit from it.
Environment
Xcode 9.3 beta 3 (9Q117m)Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, ClangImporter, Codable | |Assignee | @itaiferber | |Priority | Medium | md5: 9368c6c21550e8abd87dedbbbda09089Issue Description:
The struct imported from the Objective-C the code:
After import to Swift the `Foo` type is not Codable. It wasn't enforced in Swift 4.0, but it is in Swift 4.1
This can't be used with decoder (implementing
this code worked in Swift 4.0.3. Either it didn't work properly in Swift 4.0, or it isn't possible to import Foo as Codable. I'm feel confused.