Merge pull request #18257 from lorentey/NSObject-hashing2
[ObjectiveC] NSObject: Clarify hashing implementation
diff --git a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
index 9639638..596131a 100644
--- a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
+++ b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
@@ -195,25 +195,56 @@
//===----------------------------------------------------------------------===//
// NSObject implements Equatable's == as -[NSObject isEqual:]
-// NSObject implements Hashable's hashValue() as -[NSObject hash]
+// NSObject implements Hashable's hashValue as -[NSObject hash]
// FIXME: what about NSObjectProtocol?
extension NSObject : Equatable, Hashable {
+ /// Returns a Boolean value indicating whether two values are
+ /// equal. `NSObject` implements this by calling `lhs.isEqual(rhs)`.
+ ///
+ /// Subclasses of `NSObject` can customize Equatable conformance by overriding
+ /// `isEqual(_:)`. If two objects are equal, they must have the same hash
+ /// value, so if you override `isEqual(_:)`, make sure you also override the
+ /// `hash` property.
+ ///
+ /// - Parameters:
+ /// - lhs: A value to compare.
+ /// - rhs: Another value to compare.
public static func == (lhs: NSObject, rhs: NSObject) -> Bool {
return lhs.isEqual(rhs)
}
/// The hash value.
///
+ /// `NSObject` implements this by returning `self.hash`. Subclasses can
+ /// customize hashing by overriding the `hash` property.
+ ///
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
///
/// - Note: the hash value is not guaranteed to be stable across
/// different invocations of the same program. Do not persist the
/// hash value across program runs.
- @objc
- open var hashValue: Int {
+ @objc open // FIXME: Should be @nonobjc public. rdar://problem/42623458
+ var hashValue: Int {
return hash
}
+
+ /// Hashes the essential components of this value by feeding them into the
+ /// given hasher.
+ ///
+ /// NSObject implements this by feeding `self.hash` to the hasher. Subclasses
+ /// can customize hashing by overriding the `hash` property.
+ public func hash(into hasher: inout Hasher) {
+ // FIXME: We should combine self.hash here, but hashValue is currently
+ // overridable.
+ hasher.combine(hashValue)
+ }
+
+ public func _rawHashValue(seed: (UInt64, UInt64)) -> Int {
+ // FIXME: We should use self.hash here, but hashValue is currently
+ // overridable.
+ return self.hashValue._rawHashValue(seed: seed)
+ }
}
extension NSObject : CVarArg {