Skip to content

Commit 26b7553

Browse files
committed
Use BinaryInteger rather than (Signed|Unsigned)Integer for Error extensions.
Synchronizes corelibs Foundation with the overlay for rdar://problem/35230187.
1 parent 5b3dae9 commit 26b7553

File tree

1 file changed

+35
-70
lines changed

1 file changed

+35
-70
lines changed

Foundation/NSError.swift

Lines changed: 35 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,34 @@ public extension CustomNSError {
291291
}
292292
}
293293

294-
extension CustomNSError where Self: RawRepresentable, Self.RawValue: SignedInteger {
295-
// The error code of Error with integral raw values is the raw value.
296-
public var errorCode: Int {
297-
return numericCast(self.rawValue)
294+
/// Convert an arbitrary binary integer to an Int, reinterpreting signed ->
295+
/// unsigned if needed but trapping if the result is otherwise not
296+
/// expressible.
297+
func unsafeBinaryIntegerToInt<T: BinaryInteger>(_ value: T) -> Int {
298+
if T.isSigned {
299+
return numericCast(value)
300+
}
301+
302+
let uintValue: UInt = numericCast(value)
303+
return Int(bitPattern: uintValue)
304+
}
305+
306+
/// Convert from an Int to an arbitrary binary integer, reinterpreting signed
307+
/// -> unsigned if needed but trapping if the result is otherwise not
308+
/// expressible.
309+
func unsafeBinaryIntegerFromInt<T: BinaryInteger>(_ value: Int) -> T {
310+
if T.isSigned {
311+
return numericCast(value)
298312
}
313+
314+
let uintValue = UInt(bitPattern: value)
315+
return numericCast(uintValue)
299316
}
300317

301-
extension CustomNSError where Self: RawRepresentable, Self.RawValue: UnsignedInteger {
318+
extension CustomNSError where Self: RawRepresentable, Self.RawValue: BinaryInteger {
302319
// The error code of Error with integral raw values is the raw value.
303320
public var errorCode: Int {
304-
return numericCast(self.rawValue)
321+
return unsafeBinaryIntegerToInt(self.rawValue)
305322
}
306323
}
307324

@@ -313,12 +330,7 @@ public extension Error where Self : CustomNSError {
313330
var _code: Int { return self.errorCode }
314331
}
315332

316-
public extension Error where Self: CustomNSError, Self: RawRepresentable, Self.RawValue: SignedInteger {
317-
/// Default implementation for customized NSErrors.
318-
var _code: Int { return self.errorCode }
319-
}
320-
321-
public extension Error where Self: CustomNSError, Self: RawRepresentable, Self.RawValue: UnsignedInteger {
333+
public extension Error where Self: CustomNSError, Self: RawRepresentable, Self.RawValue: BinaryInteger {
322334
/// Default implementation for customized NSErrors.
323335
var _code: Int { return self.errorCode }
324336
}
@@ -415,42 +427,16 @@ public protocol __BridgedNSError : Error {
415427
}
416428

417429
// Allow two bridged NSError types to be compared.
418-
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: SignedInteger {
419-
public static func ==(lhs: Self, rhs: Self) -> Bool {
420-
return lhs.rawValue == rhs.rawValue
421-
}
422-
}
423-
424-
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: SignedInteger {
425-
public var _domain: String { return Self._nsErrorDomain }
426-
public var _code: Int { return Int(rawValue) }
427-
428-
public init?(rawValue: RawValue) {
429-
self = unsafeBitCast(rawValue, to: Self.self)
430-
}
431-
432-
public init?(_bridgedNSError: NSError) {
433-
if _bridgedNSError.domain != Self._nsErrorDomain {
434-
return nil
435-
}
436-
437-
self.init(rawValue: RawValue(Int(_bridgedNSError.code)))
438-
}
439-
440-
public var hashValue: Int { return _code }
441-
}
442-
443-
// Allow two bridged NSError types to be compared.
444-
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: UnsignedInteger {
430+
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: BinaryInteger {
445431
public static func ==(lhs: Self, rhs: Self) -> Bool {
446432
return lhs.rawValue == rhs.rawValue
447433
}
448434
}
449435

450-
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: UnsignedInteger {
436+
extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: BinaryInteger {
451437
public var _domain: String { return Self._nsErrorDomain }
452438
public var _code: Int {
453-
return Int(bitPattern: UInt(rawValue))
439+
return Int(rawValue)
454440
}
455441

456442
public init?(rawValue: RawValue) {
@@ -462,7 +448,7 @@ extension __BridgedNSError where Self: RawRepresentable, Self.RawValue: Unsigned
462448
return nil
463449
}
464450

465-
self.init(rawValue: RawValue(UInt(_bridgedNSError.code)))
451+
self.init(rawValue: RawValue(Int(_bridgedNSError.code)))
466452
}
467453

468454
public var hashValue: Int { return _code }
@@ -499,17 +485,16 @@ public protocol _BridgedStoredNSError : __BridgedNSError, _ObjectiveCBridgeableE
499485
}
500486

501487
/// Various helper implementations for _BridgedStoredNSError
502-
extension _BridgedStoredNSError where Code: RawRepresentable, Code.RawValue: SignedInteger {
503-
// FIXME: Generalize to Integer.
488+
extension _BridgedStoredNSError where Code: RawRepresentable, Code.RawValue: BinaryInteger {
504489
public var code: Code {
505-
return Code(rawValue: numericCast(_nsError.code))!
490+
return Code(rawValue: unsafeBinaryIntegerFromInt(_nsError.code))!
506491
}
507492

508493
/// Initialize an error within this domain with the given ``code``
509494
/// and ``userInfo``.
510495
public init(_ code: Code, userInfo: [String : Any] = [:]) {
511496
self.init(_nsError: NSError(domain: Self._nsErrorDomain,
512-
code: numericCast(code.rawValue),
497+
code: unsafeBinaryIntegerToInt(code.rawValue),
513498
userInfo: userInfo))
514499
}
515500

@@ -518,22 +503,6 @@ extension _BridgedStoredNSError where Code: RawRepresentable, Code.RawValue: Sig
518503
public var userInfo: [String : Any] { return errorUserInfo }
519504
}
520505

521-
/// Various helper implementations for _BridgedStoredNSError
522-
extension _BridgedStoredNSError where Code: RawRepresentable, Code.RawValue: UnsignedInteger {
523-
// FIXME: Generalize to Integer.
524-
public var code: Code {
525-
return Code(rawValue: numericCast(_nsError.code))!
526-
}
527-
528-
/// Initialize an error within this domain with the given ``code``
529-
/// and ``userInfo``.
530-
public init(_ code: Code, userInfo: [String : Any] = [:]) {
531-
self.init(_nsError: NSError(domain: Self._nsErrorDomain,
532-
code: numericCast(code.rawValue),
533-
userInfo: userInfo))
534-
}
535-
}
536-
537506
/// Implementation of __BridgedNSError for all _BridgedStoredNSErrors.
538507
extension _BridgedStoredNSError {
539508
/// Default implementation of ``init(_bridgedNSError)`` to provide
@@ -568,20 +537,16 @@ public extension _BridgedStoredNSError {
568537
/// Describes the code of an error.
569538
public protocol _ErrorCodeProtocol : Equatable {
570539
/// The corresponding error code.
571-
associatedtype _ErrorType
572-
573-
// FIXME: We want _ErrorType to be _BridgedStoredNSError and have its
574-
// Code match Self, but we cannot express those requirements yet.
540+
associatedtype _ErrorType: _BridgedStoredNSError
541+
where _ErrorType.Code == Self
575542
}
576543

577-
extension _ErrorCodeProtocol where Self._ErrorType: _BridgedStoredNSError {
544+
extension _ErrorCodeProtocol {
578545
/// Allow one to match an error code against an arbitrary error.
579546
public static func ~=(match: Self, error: Error) -> Bool {
580547
guard let specificError = error as? Self._ErrorType else { return false }
581548

582-
// FIXME: Work around IRGen crash when we set Code == Code._ErrorType.Code.
583-
let specificCode = specificError.code as! Self
584-
return match == specificCode
549+
return match == specificError.code
585550
}
586551
}
587552

0 commit comments

Comments
 (0)