@@ -3233,15 +3233,33 @@ public extension RawRepresentable where RawValue == String, Self : Decodable {
3233
3233
}
3234
3234
3235
3235
//===----------------------------------------------------------------------===//
3236
- // Optional Conformance
3236
+ // Optional/Collection Type Conformances
3237
3237
//===----------------------------------------------------------------------===//
3238
3238
3239
+ fileprivate func assertTypeIsEncodable< T> ( _ type: T . Type , in wrappingType: Any . Type ) {
3240
+ guard T . self is Encodable . Type else {
3241
+ if T . self == Encodable . self || T . self == Codable . self {
3242
+ preconditionFailure ( " \( wrappingType) does not conform to Encodable because Encodable does not conform to itself. You must use a concrete type to encode or decode. " )
3243
+ } else {
3244
+ preconditionFailure ( " \( wrappingType) does not conform to Encodable because \( T . self) does not conform to Encodable. " )
3245
+ }
3246
+ }
3247
+ }
3248
+
3249
+ fileprivate func assertTypeIsDecodable< T> ( _ type: T . Type , in wrappingType: Any . Type ) {
3250
+ guard T . self is Decodable . Type else {
3251
+ if T . self == Decodable . self || T . self == Codable . self {
3252
+ preconditionFailure ( " \( wrappingType) does not conform to Decodable because Decodable does not conform to itself. You must use a concrete type to encode or decode. " )
3253
+ } else {
3254
+ preconditionFailure ( " \( wrappingType) does not conform to Decodable because \( T . self) does not conform to Decodable. " )
3255
+ }
3256
+ }
3257
+ }
3258
+
3239
3259
// FIXME: Uncomment when conditional conformance is available.
3240
3260
extension Optional : Encodable /* where Wrapped : Encodable */ {
3241
3261
public func encode( to encoder: Encoder ) throws {
3242
- guard Wrapped . self is Encodable . Type else {
3243
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Encodable because \( Wrapped . self) does not conform to Encodable. " )
3244
- }
3262
+ assertTypeIsEncodable ( Wrapped . self, in: type ( of: self ) )
3245
3263
3246
3264
var container = encoder. singleValueContainer ( )
3247
3265
switch self {
@@ -3253,12 +3271,9 @@ extension Optional : Encodable /* where Wrapped : Encodable */ {
3253
3271
3254
3272
extension Optional : Decodable /* where Wrapped : Decodable */ {
3255
3273
public init ( from decoder: Decoder ) throws {
3256
- // Initialize self here so we can print type(of: self).
3274
+ // Initialize self here so we can get type(of: self).
3257
3275
self = . none
3258
-
3259
- guard Wrapped . self is Decodable . Type else {
3260
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Decodable because \( Wrapped . self) does not conform to Decodable. " )
3261
- }
3276
+ assertTypeIsDecodable ( Wrapped . self, in: type ( of: self ) )
3262
3277
3263
3278
let container = try decoder. singleValueContainer ( )
3264
3279
if !container. decodeNil ( ) {
@@ -3269,16 +3284,10 @@ extension Optional : Decodable /* where Wrapped : Decodable */ {
3269
3284
}
3270
3285
}
3271
3286
3272
- //===----------------------------------------------------------------------===//
3273
- // Collection Conformances
3274
- //===----------------------------------------------------------------------===//
3275
-
3276
3287
// FIXME: Uncomment when conditional conformance is available.
3277
3288
extension Array : Encodable /* where Element : Encodable */ {
3278
3289
public func encode( to encoder: Encoder ) throws {
3279
- guard Element . self is Encodable . Type else {
3280
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Encodable because \( Element . self) does not conform to Encodable. " )
3281
- }
3290
+ assertTypeIsEncodable ( Element . self, in: type ( of: self ) )
3282
3291
3283
3292
var container = encoder. unkeyedContainer ( )
3284
3293
for element in self {
@@ -3292,12 +3301,9 @@ extension Array : Encodable /* where Element : Encodable */ {
3292
3301
3293
3302
extension Array : Decodable /* where Element : Decodable */ {
3294
3303
public init ( from decoder: Decoder ) throws {
3295
- // Initialize self here so we can print type(of: self).
3304
+ // Initialize self here so we can get type(of: self).
3296
3305
self . init ( )
3297
-
3298
- guard Element . self is Decodable . Type else {
3299
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Decodable because \( Element . self) does not conform to Decodable. " )
3300
- }
3306
+ assertTypeIsDecodable ( Element . self, in: type ( of: self ) )
3301
3307
3302
3308
let metaType = ( Element . self as! Decodable . Type)
3303
3309
var container = try decoder. unkeyedContainer ( )
@@ -3313,9 +3319,7 @@ extension Array : Decodable /* where Element : Decodable */ {
3313
3319
3314
3320
extension Set : Encodable /* where Element : Encodable */ {
3315
3321
public func encode( to encoder: Encoder ) throws {
3316
- guard Element . self is Encodable . Type else {
3317
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Encodable because \( Element . self) does not conform to Encodable. " )
3318
- }
3322
+ assertTypeIsEncodable ( Element . self, in: type ( of: self ) )
3319
3323
3320
3324
var container = encoder. unkeyedContainer ( )
3321
3325
for element in self {
@@ -3329,12 +3333,9 @@ extension Set : Encodable /* where Element : Encodable */ {
3329
3333
3330
3334
extension Set : Decodable /* where Element : Decodable */ {
3331
3335
public init ( from decoder: Decoder ) throws {
3332
- // Initialize self here so we can print type(of: self).
3336
+ // Initialize self here so we can get type(of: self).
3333
3337
self . init ( )
3334
-
3335
- guard Element . self is Decodable . Type else {
3336
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Decodable because \( Element . self) does not conform to Decodable. " )
3337
- }
3338
+ assertTypeIsDecodable ( Element . self, in: type ( of: self ) )
3338
3339
3339
3340
let metaType = ( Element . self as! Decodable . Type)
3340
3341
var container = try decoder. unkeyedContainer ( )
@@ -3366,13 +3367,8 @@ internal struct _DictionaryCodingKey : CodingKey {
3366
3367
3367
3368
extension Dictionary : Encodable /* where Key : Encodable, Value : Encodable */ {
3368
3369
public func encode( to encoder: Encoder ) throws {
3369
- guard Key . self is Encodable . Type else {
3370
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Encodable because \( Key . self) does not conform to Encodable. " )
3371
- }
3372
-
3373
- guard Value . self is Encodable . Type else {
3374
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Encodable because \( Value . self) does not conform to Encodable. " )
3375
- }
3370
+ assertTypeIsEncodable ( Key . self, in: type ( of: self ) )
3371
+ assertTypeIsEncodable ( Value . self, in: type ( of: self ) )
3376
3372
3377
3373
if Key . self == String . self {
3378
3374
// Since the keys are already Strings, we can use them as keys directly.
@@ -3411,14 +3407,8 @@ extension Dictionary : Decodable /* where Key : Decodable, Value : Decodable */
3411
3407
public init ( from decoder: Decoder ) throws {
3412
3408
// Initialize self here so we can print type(of: self).
3413
3409
self . init ( )
3414
-
3415
- guard Key . self is Decodable . Type else {
3416
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Decodable because \( Key . self) does not conform to Decodable. " )
3417
- }
3418
-
3419
- guard Value . self is Decodable . Type else {
3420
- preconditionFailure ( " \( type ( of: self ) ) does not conform to Decodable because \( Value . self) does not conform to Decodable. " )
3421
- }
3410
+ assertTypeIsDecodable ( Key . self, in: type ( of: self ) )
3411
+ assertTypeIsDecodable ( Value . self, in: type ( of: self ) )
3422
3412
3423
3413
if Key . self == String . self {
3424
3414
// The keys are Strings, so we should be able to expect a keyed container.
0 commit comments