[test] Modernize hashing throughout the test suite

This commit is contained in:
Karoy Lorentey
2018-11-21 17:26:37 +00:00
parent 8e77a2655a
commit 666a22feff
60 changed files with 225 additions and 161 deletions

View File

@@ -110,7 +110,7 @@ class CallbackSubC : CallbackBase {
// //
class MyHashableNSObject: NSObject { class MyHashableNSObject: NSObject {
override var hashValue: Int { // expected-warning{{override of 'NSObject.hashValue' is deprecated}} override var hashValue: Int { // expected-error{{overriding non-open property outside of its defining module}} expected-error{{overriding non-@objc declarations from extensions is not supported}}
return 0 return 0
} }
} }

View File

@@ -38,7 +38,12 @@ extension Equatable {
fatalError("hella cray") fatalError("hella cray")
} }
} }
extension Hashable { public var hashValue: Int { fatalError("trill hiphy") } } extension Hashable {
public func hash(into hasher: inout Hasher) {
fatalError("trill hiphy")
}
}
extension CGSize: Hashable {} extension CGSize: Hashable {}
extension CGPoint: Hashable {} extension CGPoint: Hashable {}
extension CGRect: Hashable {} extension CGRect: Hashable {}

View File

@@ -43,7 +43,7 @@ extension LazyFilterSequence.Iterator : _ObjectiveCBridgeable { // expected-erro
struct BridgedStruct : Hashable, _ObjectiveCBridgeable { struct BridgedStruct : Hashable, _ObjectiveCBridgeable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
func _bridgeToObjectiveC() -> BridgedClass { func _bridgeToObjectiveC() -> BridgedClass {
return BridgedClass() return BridgedClass()
@@ -71,14 +71,14 @@ struct BridgedStruct : Hashable, _ObjectiveCBridgeable {
func ==(x: BridgedStruct, y: BridgedStruct) -> Bool { return true } func ==(x: BridgedStruct, y: BridgedStruct) -> Bool { return true }
struct NotBridgedStruct : Hashable { struct NotBridgedStruct : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(x: NotBridgedStruct, y: NotBridgedStruct) -> Bool { return true } func ==(x: NotBridgedStruct, y: NotBridgedStruct) -> Bool { return true }
class OtherClass : Hashable { class OtherClass : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(x: OtherClass, y: OtherClass) -> Bool { return true } func ==(x: OtherClass, y: OtherClass) -> Bool { return true }

View File

@@ -53,9 +53,7 @@ let _ = main()
public struct tinky : Equatable, Hashable { public struct tinky : Equatable, Hashable {
internal let _value: Int internal let _value: Int
public var hashValue: Int { public func hash(into hasher: inout Hasher) {}
return 0
}
} }
public func == (lhs: tinky, rhs: tinky) -> Bool { public func == (lhs: tinky, rhs: tinky) -> Bool {

View File

@@ -47,7 +47,7 @@ public func _convertObjCBoolToBool(_ x: ObjCBool) -> Bool {
} }
extension NSObject : Hashable { extension NSObject : Hashable {
@objc open var hashValue: Int { return 0 } public func hash(into hasher: inout Hasher) {}
} }
public func ==(x: NSObject, y: NSObject) -> Bool { return x === y } public func ==(x: NSObject, y: NSObject) -> Bool { return x === y }

View File

@@ -2,6 +2,9 @@
typedef struct _NSZone NSZone; typedef struct _NSZone NSZone;
typedef long NSInteger;
typedef unsigned long NSUInteger;
@protocol NSCopying @protocol NSCopying
- copyWithZone:(nullable NSZone*)z; - copyWithZone:(nullable NSZone*)z;
@end @end
@@ -14,6 +17,5 @@ typedef struct _NSZone NSZone;
+ (void) initialize; + (void) initialize;
@property (readonly, copy) NSString *description; @property (readonly, copy) NSString *description;
@property (readonly) NSUInteger hash;
@end @end
typedef long NSInteger;

View File

@@ -13,7 +13,7 @@ public struct S: Hashable {
public var z: C public var z: C
public var reabstracted: () -> () public var reabstracted: () -> ()
public var hashValue: Int { get } public func hash(into hasher: inout Hasher)
public static func ==(_: S, _: S) -> Bool public static func ==(_: S, _: S) -> Bool
} }
public class C: Hashable { public class C: Hashable {
@@ -24,7 +24,7 @@ public class C: Hashable {
public init() public init()
public var hashValue: Int { get } public func hash(into hasher: inout Hasher)
public static func ==(_: C, _: C) -> Bool public static func ==(_: C, _: C) -> Bool
} }

View File

@@ -191,7 +191,7 @@ class Bas : NSObject {
deinit { var x = 10 } deinit { var x = 10 }
override var hashValue: Int { return 0 } override var hash: Int { return 0 }
@objc func acceptSet(_ set: Set<Bas>) { } @objc func acceptSet(_ set: Set<Bas>) { }
} }

View File

@@ -77,6 +77,9 @@ extension NSObject : Equatable, Hashable {
public var hashValue: Int { public var hashValue: Int {
return hash return hash
} }
public func hash(into hasher: inout Hasher) {
hasher.combine(hash)
}
} }
public func == (lhs: NSObject, rhs: NSObject) -> Bool { public func == (lhs: NSObject, rhs: NSObject) -> Bool {

View File

@@ -60,8 +60,8 @@ public struct Selector : ExpressibleByStringLiteral {
self = sel_registerName(value) self = sel_registerName(value)
} }
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
return ptr.hashValue hasher.combine(ptr)
} }
} }
@@ -88,12 +88,16 @@ public func ~=(x: NSObject, y: NSObject) -> Bool {
} }
extension NSObject : Equatable, Hashable { extension NSObject : Equatable, Hashable {
@objc open var hashValue: Int {
return hash
}
public static func == (lhs: NSObject, rhs: NSObject) -> Bool { public static func == (lhs: NSObject, rhs: NSObject) -> Bool {
return lhs.isEqual(rhs) return lhs.isEqual(rhs)
} }
public var hashValue: Int {
return hash
}
public func hash(into hasher: inout Hasher) {
hasher.combine(hash)
}
} }

View File

@@ -272,8 +272,9 @@ FunctionConversionTestSuite.test("CollectionUpCastsInFuncParameters") {
protocol X: Hashable {} protocol X: Hashable {}
class B: X { class B: X {
var hashValue: Int { return 42 } var hashValue: Int { return 42 }
func hash(into hasher: inout Hasher) {}
static func == (lhs: B, rhs: B) -> Bool { static func == (lhs: B, rhs: B) -> Bool {
return lhs.hashValue == rhs.hashValue return true
} }
} }

View File

@@ -23,8 +23,8 @@ struct A : Preening, Hashable, Equatable {
return lhs.value == rhs.value return lhs.value == rhs.value
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {
return value.hashValue hasher.combine(value)
} }
} }

View File

@@ -52,17 +52,29 @@ EnumSynthesisTests.test("CloseGenericValuesDoNotCollide") {
expectNotEqual(Combo<String, Int>.both("foo", 3).hashValue, Combo<String, Int>.both("goo", 4).hashValue) expectNotEqual(Combo<String, Int>.both("foo", 3).hashValue, Combo<String, Int>.both("goo", 4).hashValue)
} }
func hashEncode(_ body: (inout Hasher) -> ()) -> Int {
var hasher = Hasher()
body(&hasher)
return hasher.finalize()
}
// Make sure that if the user overrides the synthesized member, that one gets // Make sure that if the user overrides the synthesized member, that one gets
// used instead. // used instead.
enum Overrides: Hashable { enum Overrides: Hashable {
case a(Int), b(String) case a(Int), b(String)
var hashValue: Int { return 2 } var hashValue: Int { return 2 }
func hash(into hasher: inout Hasher) {
hasher.combine(2)
}
static func == (lhs: Overrides, rhs: Overrides) -> Bool { return true } static func == (lhs: Overrides, rhs: Overrides) -> Bool { return true }
} }
EnumSynthesisTests.test("ExplicitOverridesSynthesized") { EnumSynthesisTests.test("ExplicitOverridesSynthesized") {
checkHashable(expectedEqual: true, Overrides.a(4), .b("foo")) checkHashable(expectedEqual: true, Overrides.a(4), .b("foo"))
expectEqual(Overrides.a(4).hashValue, 2) expectEqual(Overrides.a(4).hashValue, 2)
expectEqual(
hashEncode { $0.combine(Overrides.a(4)) },
hashEncode { $0.combine(2) })
} }
// ...even in an extension. // ...even in an extension.
@@ -71,12 +83,18 @@ enum OverridesInExtension: Hashable {
} }
extension OverridesInExtension { extension OverridesInExtension {
var hashValue: Int { return 2 } var hashValue: Int { return 2 }
func hash(into hasher: inout Hasher) {
hasher.combine(2)
}
static func == (lhs: OverridesInExtension, rhs: OverridesInExtension) -> Bool { return true } static func == (lhs: OverridesInExtension, rhs: OverridesInExtension) -> Bool { return true }
} }
EnumSynthesisTests.test("ExplicitOverridesSynthesizedInExtension") { EnumSynthesisTests.test("ExplicitOverridesSynthesizedInExtension") {
checkHashable(expectedEqual: true, OverridesInExtension.a(4), .b("foo")) checkHashable(expectedEqual: true, OverridesInExtension.a(4), .b("foo"))
expectEqual(OverridesInExtension.a(4).hashValue, 2) expectEqual(OverridesInExtension.a(4).hashValue, 2)
expectEqual(
hashEncode { $0.combine(OverridesInExtension.a(4)) },
hashEncode { $0.combine(2) })
} }
// Try an indirect enum. // Try an indirect enum.

View File

@@ -40,17 +40,29 @@ StructSynthesisTests.test("CloseGenericValuesDoNotCollide") {
expectNotEqual(PSI(a: "foo", b: 0).hashValue, PSI(a: "goo", b: 1).hashValue) expectNotEqual(PSI(a: "foo", b: 0).hashValue, PSI(a: "goo", b: 1).hashValue)
} }
func hashEncode(_ body: (inout Hasher) -> ()) -> Int {
var hasher = Hasher()
body(&hasher)
return hasher.finalize()
}
// Make sure that if the user overrides the synthesized member, that one gets // Make sure that if the user overrides the synthesized member, that one gets
// used instead. // used instead.
struct Overrides: Hashable { struct Overrides: Hashable {
let a: Int let a: Int
var hashValue: Int { return 2 } var hashValue: Int { return 2 }
func hash(into hasher: inout Hasher) {
hasher.combine(2)
}
static func == (lhs: Overrides, rhs: Overrides) -> Bool { return true } static func == (lhs: Overrides, rhs: Overrides) -> Bool { return true }
} }
StructSynthesisTests.test("ExplicitOverridesSynthesized") { StructSynthesisTests.test("ExplicitOverridesSynthesized") {
checkHashable(expectedEqual: true, Overrides(a: 4), Overrides(a: 5)) checkHashable(expectedEqual: true, Overrides(a: 4), Overrides(a: 5))
expectEqual(Overrides(a: 4).hashValue, 2) expectEqual(Overrides(a: 4).hashValue, 2)
expectEqual(
hashEncode { $0.combine(Overrides(a: 4)) },
hashEncode { $0.combine(2) })
} }
// ...even in an extension. // ...even in an extension.
@@ -59,12 +71,18 @@ struct OverridesInExtension: Hashable {
} }
extension OverridesInExtension { extension OverridesInExtension {
var hashValue: Int { return 2 } var hashValue: Int { return 2 }
func hash(into hasher: inout Hasher) {
hasher.combine(2)
}
static func == (lhs: OverridesInExtension, rhs: OverridesInExtension) -> Bool { return true } static func == (lhs: OverridesInExtension, rhs: OverridesInExtension) -> Bool { return true }
} }
StructSynthesisTests.test("ExplicitOverridesSynthesizedInExtension") { StructSynthesisTests.test("ExplicitOverridesSynthesizedInExtension") {
checkHashable(expectedEqual: true, OverridesInExtension(a: 4), OverridesInExtension(a: 5)) checkHashable(expectedEqual: true, OverridesInExtension(a: 4), OverridesInExtension(a: 5))
expectEqual(OverridesInExtension(a: 4).hashValue, 2) expectEqual(OverridesInExtension(a: 4).hashValue, 2)
expectEqual(
hashEncode { $0.combine(OverridesInExtension(a: 4)) },
hashEncode { $0.combine(2) })
} }
runAllTests() runAllTests()

View File

@@ -1064,17 +1064,9 @@ public struct _BigInt<Word: FixedWidthInteger & UnsignedInteger> :
//===--- Hashable -------------------------------------------------------===// //===--- Hashable -------------------------------------------------------===//
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
#if arch(i386) || arch(arm) hasher.combine(isNegative)
let p: UInt = 16777619 hasher.combine(_data)
let h: UInt = (2166136261 &* p) ^ (isNegative ? 1 : 0)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
let p: UInt = 1099511628211
let h: UInt = (14695981039346656037 &* p) ^ (isNegative ? 1 : 0)
#else
fatalError("Unimplemented")
#endif
return Int(bitPattern: _data.reduce(h, { ($0 &* p) ^ UInt($1) }))
} }
//===--- Bit shifting operators -----------------------------------------===// //===--- Bit shifting operators -----------------------------------------===//
@@ -1282,8 +1274,8 @@ struct Bit : FixedWidthInteger, UnsignedInteger {
// Hashable, CustomStringConvertible // Hashable, CustomStringConvertible
var hashValue: Int { func hash(into hasher: inout Hasher) {
return Int(value) hasher.combine(value)
} }
var description: String { var description: String {

View File

@@ -206,8 +206,8 @@ import Dispatch
public struct _stdlib_pthread_t : Equatable, Hashable { public struct _stdlib_pthread_t : Equatable, Hashable {
internal let _value: pthread_t internal let _value: pthread_t
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
return _value.hashValue hasher.combine(_value)
} }
} }

View File

@@ -10,7 +10,7 @@ struct S: Hashable {
let y: String let y: String
var z: C var z: C
var hashValue: Int { get } func hash(into hasher: inout Hasher)
static func ==(x: S, y: S) -> Bool static func ==(x: S, y: S) -> Bool
} }
class C: Hashable { class C: Hashable {
@@ -23,7 +23,7 @@ class C: Hashable {
get set get set
} }
var hashValue: Int { get } func hash(into hasher: inout Hasher)
static func ==(x: C, y: C) -> Bool static func ==(x: C, y: C) -> Bool
} }

View File

@@ -14,7 +14,7 @@ struct S: Hashable {
let y: String let y: String
var z: C var z: C
var hashValue: Int { get } func hash(into hasher: inout Hasher)
static func ==(x: S, y: S) -> Bool static func ==(x: S, y: S) -> Bool
} }
class C: Hashable { class C: Hashable {
@@ -27,7 +27,7 @@ class C: Hashable {
get set get set
} }
var hashValue: Int { get } func hash(into hasher: inout Hasher)
static func ==(x: C, y: C) -> Bool static func ==(x: C, y: C) -> Bool
} }

View File

@@ -35,7 +35,7 @@ public struct Selector : ExpressibleByStringLiteral {
} }
extension NSObject : Hashable { extension NSObject : Hashable {
public var hashValue: Int { return 0 } public func hash(into hasher: inout Hasher) {}
public static func == (x: NSObject, y: NSObject) -> Bool { return true } public static func == (x: NSObject, y: NSObject) -> Bool { return true }
} }

View File

@@ -1,3 +1,5 @@
extension Thing : Hashable { extension Thing : Hashable {
var hashValue: Int { return value } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
} }

View File

@@ -6,7 +6,7 @@
class MyClass {} class MyClass {}
class KeyClass : Hashable { class KeyClass : Hashable {
var hashValue : Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(lhs: KeyClass, rhs: KeyClass) -> Bool { return true } func ==(lhs: KeyClass, rhs: KeyClass) -> Bool { return true }

View File

@@ -20,7 +20,7 @@ class BridgedObjC : NSObject { }
func == (x: BridgedObjC, y: BridgedObjC) -> Bool { return true } func == (x: BridgedObjC, y: BridgedObjC) -> Bool { return true }
struct BridgedSwift : Hashable, _ObjectiveCBridgeable { struct BridgedSwift : Hashable, _ObjectiveCBridgeable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
func _bridgeToObjectiveC() -> BridgedObjC { func _bridgeToObjectiveC() -> BridgedObjC {
return BridgedObjC() return BridgedObjC()

View File

@@ -17,8 +17,9 @@ func array_downcast(array: [Any]) -> [S]? {
} }
extension S : Hashable { extension S : Hashable {
var hashValue : Int { func hash(into hasher: inout Hasher) {
return x + y hasher.combine(x)
hasher.combine(y)
} }
} }
func ==(lhs: S, rhs: S) -> Bool { func ==(lhs: S, rhs: S) -> Bool {

View File

@@ -17,8 +17,9 @@ func array_upcast(array: [S]) -> [Any] {
} }
extension S : Hashable { extension S : Hashable {
var hashValue : Int { func hash(into hasher: inout Hasher) {
return x + y hasher.combine(x)
hasher.combine(y)
} }
} }
func ==(lhs: S, rhs: S) -> Bool { func ==(lhs: S, rhs: S) -> Bool {

View File

@@ -21,7 +21,7 @@ class BridgedObjC : NSObject { }
func == (x: BridgedObjC, y: BridgedObjC) -> Bool { return true } func == (x: BridgedObjC, y: BridgedObjC) -> Bool { return true }
struct BridgedSwift : Hashable, _ObjectiveCBridgeable { struct BridgedSwift : Hashable, _ObjectiveCBridgeable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
func _bridgeToObjectiveC() -> BridgedObjC { func _bridgeToObjectiveC() -> BridgedObjC {
return BridgedObjC() return BridgedObjC()

View File

@@ -605,10 +605,8 @@ func rdar35702810() {
protocol X: Hashable {} protocol X: Hashable {}
class B: X { class B: X {
var hashValue: Int { return 42 } func hash(into hasher: inout Hasher) {}
static func == (lhs: B, rhs: B) -> Bool { static func == (lhs: B, rhs: B) -> Bool { return true }
return lhs.hashValue == rhs.hashValue
}
} }
func bar_arr<T: X>(type: T.Type, _ fn: ([T]?) -> Void) {} func bar_arr<T: X>(type: T.Type, _ fn: ([T]?) -> Void) {}

View File

@@ -280,7 +280,7 @@ func iuoKeyPaths() {
class Bass: Hashable { class Bass: Hashable {
static func ==(_: Bass, _: Bass) -> Bool { return false } static func ==(_: Bass, _: Bass) -> Bool { return false }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
class Treble: Bass { } class Treble: Bass { }

View File

@@ -923,10 +923,8 @@ class MyThing: Hashable {
deinit { deinit {
Swift.print("Deinit \(name)") Swift.print("Deinit \(name)")
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
static func ==(lhs: MyThing, rhs: MyThing) -> Bool { static func ==(lhs: MyThing, rhs: MyThing) -> Bool {
return false return false

View File

@@ -29,9 +29,9 @@ extension Version: Hashable {
return lhs.major == rhs.major && return lhs.major == rhs.major &&
lhs.buildMetadataIdentifiers == rhs.buildMetadataIdentifiers lhs.buildMetadataIdentifiers == rhs.buildMetadataIdentifiers
} }
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
var result: UInt64 = 0 hasher.combine(major)
return Int(truncatingIfNeeded: result) hasher.combine(buildMetadataIdentifiers)
} }
} }

View File

@@ -40,7 +40,7 @@ public func getGenericContainer<T>(g: G<T>, e: T.Elt) -> T where T.Elt : AnElt
enum ArithmeticError : Error { enum ArithmeticError : Error {
case DivByZero case DivByZero
var hashValue: Int { get } func hash(into hasher: inout Hasher)
var _code: Int { get } var _code: Int { get }
} }

View File

@@ -12,7 +12,7 @@ struct MMStorage<Key : Hashable, Value> {
func ==(lhs: MMObject, rhs: MMObject) -> Bool func ==(lhs: MMObject, rhs: MMObject) -> Bool
class MMObject : Hashable { class MMObject : Hashable {
var hashValue: Int { get } func hash(into hasher: inout Hasher)
} }
class MMString : MMObject { class MMString : MMObject {

View File

@@ -43,7 +43,7 @@ func localEnum() -> Bool {
enum CustomHashable { enum CustomHashable {
case A, B case A, B
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(x: CustomHashable, y: CustomHashable) -> Bool { func ==(x: CustomHashable, y: CustomHashable) -> Bool {
return true return true
@@ -239,7 +239,7 @@ extension OtherFileNonconforming: Hashable {
static func ==(lhs: OtherFileNonconforming, rhs: OtherFileNonconforming) -> Bool { static func ==(lhs: OtherFileNonconforming, rhs: OtherFileNonconforming) -> Bool {
return true return true
} }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
// ...but synthesis in a type defined in another file doesn't work yet. // ...but synthesis in a type defined in another file doesn't work yet.
extension YetOtherFileNonconforming: Equatable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}} extension YetOtherFileNonconforming: Equatable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}}

View File

@@ -48,9 +48,8 @@ struct CustomHashValue: Hashable {
let x: Int let x: Int
let y: Int let y: Int
var hashValue: Int { return 0 }
static func ==(x: CustomHashValue, y: CustomHashValue) -> Bool { return true } static func ==(x: CustomHashValue, y: CustomHashValue) -> Bool { return true }
func hash(into hasher: inout Hasher) {}
} }
func customHashValue() { func customHashValue() {
@@ -192,7 +191,7 @@ extension OtherFileNonconforming: Hashable {
static func ==(lhs: OtherFileNonconforming, rhs: OtherFileNonconforming) -> Bool { static func ==(lhs: OtherFileNonconforming, rhs: OtherFileNonconforming) -> Bool {
return true return true
} }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
// ...but synthesis in a type defined in another file doesn't work yet. // ...but synthesis in a type defined in another file doesn't work yet.
extension YetOtherFileNonconforming: Equatable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}} extension YetOtherFileNonconforming: Equatable {} // expected-error {{cannot be automatically synthesized in an extension in a different file to the type}}

View File

@@ -2186,8 +2186,8 @@ class ConformsToProtocolThrowsObjCName2 : ProtocolThrowsObjCName {
@nonobjc final func objc_ext_objc_explicit_nonobjc(_: PlainStruct) { } @nonobjc final func objc_ext_objc_explicit_nonobjc(_: PlainStruct) { }
} }
@objc class ObjC_Class1 : Hashable { @objc class ObjC_Class1 : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(lhs: ObjC_Class1, rhs: ObjC_Class1) -> Bool { func ==(lhs: ObjC_Class1, rhs: ObjC_Class1) -> Bool {

View File

@@ -21,16 +21,16 @@ class infer_instanceVar1 {
} }
} }
class ObjC_Class1 : NSObject, Hashable { class ObjC_Class1 : NSObject, Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(lhs: ObjC_Class1, rhs: ObjC_Class1) -> Bool { func ==(lhs: ObjC_Class1, rhs: ObjC_Class1) -> Bool {
return true return true
} }
@objc class ObjC_Class2 : Hashable { @objc class ObjC_Class2 : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
func ==(lhs: ObjC_Class2, rhs: ObjC_Class2) -> Bool { func ==(lhs: ObjC_Class2, rhs: ObjC_Class2) -> Bool {

View File

@@ -1,9 +1,7 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown // RUN: %target-typecheck-verify-swift -verify-ignore-unknown
struct NonCodable : Hashable { struct NonCodable : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 1
}
static func ==(_ lhs: NonCodable, _ rhs: NonCodable) -> Bool { static func ==(_ lhs: NonCodable, _ rhs: NonCodable) -> Bool {
return true return true

View File

@@ -1,9 +1,7 @@
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown // RUN: %target-typecheck-verify-swift -verify-ignore-unknown
struct NonCodable : Hashable { struct NonCodable : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 1
}
static func ==(_ lhs: NonCodable, _ rhs: NonCodable) -> Bool { static func ==(_ lhs: NonCodable, _ rhs: NonCodable) -> Bool {
return true return true

View File

@@ -12,10 +12,8 @@ public extension _ObjectiveCBridgeable {
} }
} }
class Root : Hashable { class Root : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func ==(x: Root, y: Root) -> Bool { return true } func ==(x: Root, y: Root) -> Bool { return true }
@@ -42,9 +40,7 @@ struct BridgedToObjC : Hashable, _ObjectiveCBridgeable {
return true return true
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func ==(x: BridgedToObjC, y: BridgedToObjC) -> Bool { return true } func ==(x: BridgedToObjC, y: BridgedToObjC) -> Bool { return true }

View File

@@ -3,8 +3,8 @@
class C : Hashable { class C : Hashable {
var x = 0 var x = 0
var hashValue: Int { func hash(into hasher: inout Hasher) {
return x hasher.combine(x)
} }
} }

View File

@@ -3,8 +3,8 @@
class C : Hashable { class C : Hashable {
var x = 0 var x = 0
var hashValue: Int { func hash(into hasher: inout Hasher) {
return x hasher.combine(x)
} }
} }
@@ -14,10 +14,8 @@ func == (x: C, y: C) -> Bool { return true }
class D : C {} class D : C {}
// Unrelated to the classes above. // Unrelated to the classes above.
class U : Hashable { class U : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func == (x: U, y: U) -> Bool { return true } func == (x: U, y: U) -> Bool { return true }

View File

@@ -1,7 +1,7 @@
// RUN: %target-typecheck-verify-swift // RUN: %target-typecheck-verify-swift
class Base : Hashable { class Base : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
class Derived : Base { } class Derived : Base { }

View File

@@ -12,10 +12,8 @@ public extension _ObjectiveCBridgeable {
} }
} }
class Root : Hashable { class Root : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func ==(x: Root, y: Root) -> Bool { return true } func ==(x: Root, y: Root) -> Bool { return true }
@@ -44,9 +42,7 @@ struct BridgedToObjC : Hashable, _ObjectiveCBridgeable {
return true return true
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func ==(x: BridgedToObjC, y: BridgedToObjC) -> Bool { return true } func ==(x: BridgedToObjC, y: BridgedToObjC) -> Bool { return true }

View File

@@ -3,8 +3,8 @@
class C : Hashable { class C : Hashable {
var x = 0 var x = 0
var hashValue: Int { func hash(into hasher: inout Hasher) {
return x hasher.combine(x)
} }
} }

View File

@@ -3,8 +3,8 @@
class C : Hashable { class C : Hashable {
var x = 0 var x = 0
var hashValue: Int { func hash(into hasher: inout Hasher) {
return x hasher.combine(x)
} }
} }
@@ -15,9 +15,7 @@ class D : C {}
// Unrelated to the classes above. // Unrelated to the classes above.
class U : Hashable { class U : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {}
return 0
}
} }
func == (x: U, y: U) -> Bool { return true } func == (x: U, y: U) -> Bool { return true }

View File

@@ -2,11 +2,11 @@
struct Sub: Hashable { struct Sub: Hashable {
static func ==(_: Sub, _: Sub) -> Bool { return true } static func ==(_: Sub, _: Sub) -> Bool { return true }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
struct OptSub: Hashable { struct OptSub: Hashable {
static func ==(_: OptSub, _: OptSub) -> Bool { return true } static func ==(_: OptSub, _: OptSub) -> Bool { return true }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
struct NonHashableSub {} struct NonHashableSub {}
@@ -33,7 +33,7 @@ struct A: Hashable {
subscript(sub: Sub) -> A { get { return self } set { } } subscript(sub: Sub) -> A { get { return self } set { } }
static func ==(_: A, _: A) -> Bool { fatalError() } static func ==(_: A, _: A) -> Bool { fatalError() }
var hashValue: Int { fatalError() } func hash(into hasher: inout Hasher) { fatalError() }
} }
struct B {} struct B {}
struct C<T> { struct C<T> {
@@ -486,7 +486,7 @@ func testStaticKeyPathComponent() {
class Bass: Hashable { class Bass: Hashable {
static func ==(_: Bass, _: Bass) -> Bool { return false } static func ==(_: Bass, _: Bass) -> Bool { return false }
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
} }
class Treble: Bass { } class Treble: Bass { }

View File

@@ -26,7 +26,9 @@ struct HashableStruct : Hashable {
static func ==(lhs: HashableStruct, rhs: HashableStruct) -> Bool { static func ==(lhs: HashableStruct, rhs: HashableStruct) -> Bool {
return lhs.value == rhs.value return lhs.value == rhs.value
} }
var hashValue : Int { return value } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
} }
class HashableClass : Hashable { class HashableClass : Hashable {
@@ -35,7 +37,9 @@ class HashableClass : Hashable {
static func ==(lhs: HashableClass, rhs: HashableClass) -> Bool { static func ==(lhs: HashableClass, rhs: HashableClass) -> Bool {
return lhs.value == rhs.value return lhs.value == rhs.value
} }
var hashValue : Int { return value } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
} }
enum HashableEnum : Hashable { enum HashableEnum : Hashable {
@@ -45,9 +49,10 @@ enum HashableEnum : Hashable {
case (.value(let l), .value(let r)): return l == r case (.value(let l), .value(let r)): return l == r
} }
} }
var hashValue : Int { func hash(into hasher: inout Hasher) {
switch self { switch self {
case .value(let v): return v case .value(let v):
hasher.combine(v)
} }
} }
} }

View File

@@ -42,7 +42,7 @@ struct MyInt: FixedWidthInteger { // expected-error {{type 'MyInt' does not conf
func quotientAndRemainder(dividingBy rhs: MyInt) -> (quotient: MyInt, remainder: MyInt) { fatalError() } func quotientAndRemainder(dividingBy rhs: MyInt) -> (quotient: MyInt, remainder: MyInt) { fatalError() }
func signum() -> MyInt { fatalError() } func signum() -> MyInt { fatalError() }
var hashValue: Int { fatalError() } func hash(into hasher: inout Hasher) { fatalError() }
var byteSwapped: MyInt { fatalError() } var byteSwapped: MyInt { fatalError() }
static var max: MyInt { fatalError() } static var max: MyInt { fatalError() }
static var min: MyInt { fatalError() } static var min: MyInt { fatalError() }

View File

@@ -33,8 +33,9 @@ struct KnownUnbridged: Equatable, Hashable {
return a.x === b.x && a.y === b.y return a.x === b.x && a.y === b.y
} }
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
return x.hashValue ^ y.hashValue hasher.combine(x)
hasher.combine(y)
} }
} }

View File

@@ -235,6 +235,10 @@ var _bridgedKeyBridgeOperations = _stdlib_AtomicInt(0)
struct TestBridgedKeyTy struct TestBridgedKeyTy
: Equatable, Hashable, CustomStringConvertible, _ObjectiveCBridgeable { : Equatable, Hashable, CustomStringConvertible, _ObjectiveCBridgeable {
var value: Int
var _hashValue: Int
var serial: Int
static var bridgeOperations: Int { static var bridgeOperations: Int {
get { get {
return _bridgedKeyBridgeOperations.load() return _bridgedKeyBridgeOperations.load()
@@ -259,6 +263,10 @@ struct TestBridgedKeyTy
return _hashValue return _hashValue
} }
func hash(into hasher: inout Hasher) {
hasher.combine(_hashValue)
}
func _bridgeToObjectiveC() -> TestObjCKeyTy { func _bridgeToObjectiveC() -> TestObjCKeyTy {
_bridgedKeyBridgeOperations.fetchAndAdd(1) _bridgedKeyBridgeOperations.fetchAndAdd(1)
return TestObjCKeyTy(value) return TestObjCKeyTy(value)
@@ -286,10 +294,6 @@ struct TestBridgedKeyTy
_forceBridgeFromObjectiveC(source!, result: &result) _forceBridgeFromObjectiveC(source!, result: &result)
return result! return result!
} }
var value: Int
var _hashValue: Int
var serial: Int
} }
func == (lhs: TestBridgedKeyTy, rhs: TestBridgedKeyTy) -> Bool { func == (lhs: TestBridgedKeyTy, rhs: TestBridgedKeyTy) -> Bool {

View File

@@ -96,8 +96,8 @@ extension MockBinaryInteger : Comparable {
} }
extension MockBinaryInteger : Hashable { extension MockBinaryInteger : Hashable {
var hashValue: Int { func hash(into hasher: inout Hasher) {
return _value.hashValue hasher.combine(_value)
} }
} }

View File

@@ -592,7 +592,9 @@ struct KeyA: Hashable {
init(value: String) { self.value = value } init(value: String) { self.value = value }
static func ==(a: KeyA, b: KeyA) -> Bool { return a.value == b.value } static func ==(a: KeyA, b: KeyA) -> Bool { return a.value == b.value }
var hashValue: Int { return value.hashValue } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
} }
struct KeyB: Hashable { struct KeyB: Hashable {
var canary = LifetimeTracked(2222) var canary = LifetimeTracked(2222)
@@ -602,7 +604,9 @@ struct KeyB: Hashable {
init(value: Int) { self.value = value } init(value: Int) { self.value = value }
static func ==(a: KeyB, b: KeyB) -> Bool { return a.value == b.value } static func ==(a: KeyB, b: KeyB) -> Bool { return a.value == b.value }
var hashValue: Int { return value.hashValue } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
} }
func fullGenericContext<T: Hashable, U: Hashable>(x: T, y: U) -> KeyPath<Subscripts<T>, SubscriptResult<T, U>> { func fullGenericContext<T: Hashable, U: Hashable>(x: T, y: U) -> KeyPath<Subscripts<T>, SubscriptResult<T, U>> {

View File

@@ -70,7 +70,9 @@ tests.test("wrapped value") {
struct NotBridged: Hashable { struct NotBridged: Hashable {
var x: Int var x: Int
var hashValue: Int { return x } func hash(into hasher: inout Hasher) {
hasher.combine(x)
}
static func ==(x: NotBridged, y: NotBridged) -> Bool { static func ==(x: NotBridged, y: NotBridged) -> Bool {
return x.x == y.x return x.x == y.x

View File

@@ -18,8 +18,8 @@ struct NotBridgedKeyTy : Equatable, Hashable {
init(_ value: Int) { init(_ value: Int) {
self.value = value self.value = value
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {
return value hasher.combine(value)
} }
var value: Int var value: Int
} }
@@ -38,8 +38,8 @@ class BridgedVerbatimRefTy : Equatable, Hashable {
init(_ value: Int) { init(_ value: Int) {
self.value = value self.value = value
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {
return value hasher.combine(value)
} }
var value: Int var value: Int
} }
@@ -83,7 +83,9 @@ class TestObjCKeyTy : NSObject {
struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable { struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable {
init(_ value: Int) { self.value = value } init(_ value: Int) { self.value = value }
var hashValue: Int { return value } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
func _bridgeToObjectiveC() -> TestObjCKeyTy { func _bridgeToObjectiveC() -> TestObjCKeyTy {
return TestObjCKeyTy(value) return TestObjCKeyTy(value)

View File

@@ -42,7 +42,12 @@ struct SomeStructure: Hashable {
} }
// FIXME: we don't care about this, but Any only finds == on Hashables // FIXME: we don't care about this, but Any only finds == on Hashables
var hashValue: Int { return i } func hash(into hasher: inout Hasher) {
hasher.combine(i)
hasher.combine(str)
hasher.combine(sub.i)
hasher.combine(sub.str)
}
} }
/* /*

View File

@@ -35,7 +35,7 @@ struct NotHashable { }
var nh1 : [NotHashable : Int] // expected-error{{'NotHashable' does not conform to protocol 'Hashable'}} var nh1 : [NotHashable : Int] // expected-error{{'NotHashable' does not conform to protocol 'Hashable'}}
struct Y<T> : Hashable { struct Y<T> : Hashable {
var hashValue: Int { return 0 } func hash(into hasher: inout Hasher) {}
static func ==(this: Y<T>, other: Y<T>) -> Bool { return true } static func ==(this: Y<T>, other: Y<T>) -> Bool { return true }
} }

View File

@@ -214,6 +214,9 @@ ${kw} HasCustomRepresentation_${name}
var hashValue: Int { var hashValue: Int {
return value return value
} }
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
func _toCustomAnyHashable() -> AnyHashable? { func _toCustomAnyHashable() -> AnyHashable? {
if hasDefaultAnyHashableRepresentation { if hasDefaultAnyHashableRepresentation {
return nil return nil
@@ -248,6 +251,9 @@ ${kw} HasCustomRepresentation_Generic${name}<Wrapped>
var hashValue: Int { var hashValue: Int {
return asGenericMinimalHashableValue.hashValue return asGenericMinimalHashableValue.hashValue
} }
func hash(into hasher: inout Hasher) {
hasher.combine(asGenericMinimalHashableValue)
}
func _toCustomAnyHashable() -> AnyHashable? { func _toCustomAnyHashable() -> AnyHashable? {
if hasDefaultAnyHashableRepresentation { if hasDefaultAnyHashableRepresentation {
return nil return nil
@@ -360,6 +366,9 @@ struct HasCustomRepresentationRecursively
var hashValue: Int { var hashValue: Int {
return value return value
} }
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
func _toCustomAnyHashable() -> AnyHashable? { func _toCustomAnyHashable() -> AnyHashable? {
if value == 0 { if value == 0 {
return AnyHashable(HasCustomRepresentationRecursively(value + 1)) return AnyHashable(HasCustomRepresentationRecursively(value + 1))
@@ -457,6 +466,9 @@ class ${hashable_base.full_name} : ${', '.join([b.full_name for b in bases])} {
var hashValue: Int { var hashValue: Int {
return value return value
} }
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
static func == ${hashable_base.generic_parameters_decl} ( static func == ${hashable_base.generic_parameters_decl} (
lhs: ${hashable_base.full_name}, lhs: ${hashable_base.full_name},
rhs: ${hashable_base.full_name} rhs: ${hashable_base.full_name}
@@ -697,14 +709,14 @@ enum MinimalHashableRCSwiftError : Error, Hashable {
case caseB(LifetimeTracked) case caseB(LifetimeTracked)
case caseC(LifetimeTracked) case caseC(LifetimeTracked)
var hashValue: Int { func hash(into hasher: inout Hasher) {
switch self { switch self {
case .caseA: case .caseA:
return 10 hasher.combine(10)
case .caseB: case .caseB:
return 20 hasher.combine(20)
case .caseC: case .caseC:
return 30 hasher.combine(30)
} }
} }

View File

@@ -18,12 +18,12 @@
import StdlibUnittest import StdlibUnittest
class Base : Hashable { class Base : Hashable {
var value: Int
init(_ value: Int) { init(_ value: Int) {
self.value = value self.value = value
} }
var value: Int func hash(into hasher: inout Hasher) {
var hashValue : Int { hasher.combine(value)
return value.hashValue
} }
} }

View File

@@ -17,13 +17,15 @@ let testSuiteSuffix = _isDebugAssertConfiguration() ? "_debug" : "_release"
var DictionaryTraps = TestSuite("DictionaryTraps" + testSuiteSuffix) var DictionaryTraps = TestSuite("DictionaryTraps" + testSuiteSuffix)
struct NotBridgedKeyTy : Equatable, Hashable { struct NotBridgedKeyTy : Equatable, Hashable {
var value: Int
init(_ value: Int) { init(_ value: Int) {
self.value = value self.value = value
} }
var hashValue: Int {
return value func hash(into hasher: inout Hasher) {
hasher.combine(value)
} }
var value: Int
} }
func == (lhs: NotBridgedKeyTy, rhs: NotBridgedKeyTy) -> Bool { func == (lhs: NotBridgedKeyTy, rhs: NotBridgedKeyTy) -> Bool {
@@ -37,13 +39,14 @@ struct NotBridgedValueTy {}
assert(!_isBridgedToObjectiveC(NotBridgedValueTy.self)) assert(!_isBridgedToObjectiveC(NotBridgedValueTy.self))
class BridgedVerbatimRefTy : Equatable, Hashable { class BridgedVerbatimRefTy : Equatable, Hashable {
var value: Int
init(_ value: Int) { init(_ value: Int) {
self.value = value self.value = value
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {
return value hasher.combine(value)
} }
var value: Int
} }
func == (lhs: BridgedVerbatimRefTy, rhs: BridgedVerbatimRefTy) -> Bool { func == (lhs: BridgedVerbatimRefTy, rhs: BridgedVerbatimRefTy) -> Bool {
@@ -81,9 +84,13 @@ class TestObjCKeyTy : NSObject {
} }
struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable { struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable {
var value: Int
init(_ value: Int) { self.value = value } init(_ value: Int) { self.value = value }
var hashValue: Int { return value } func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
func _bridgeToObjectiveC() -> TestObjCKeyTy { func _bridgeToObjectiveC() -> TestObjCKeyTy {
return TestObjCKeyTy(value) return TestObjCKeyTy(value)
@@ -110,8 +117,6 @@ struct TestBridgedKeyTy : Hashable, _ObjectiveCBridgeable {
_forceBridgeFromObjectiveC(source!, result: &result) _forceBridgeFromObjectiveC(source!, result: &result)
return result! return result!
} }
var value: Int
} }
func ==(x: TestBridgedKeyTy, y: TestBridgedKeyTy) -> Bool { func ==(x: TestBridgedKeyTy, y: TestBridgedKeyTy) -> Bool {

View File

@@ -5,8 +5,8 @@ import StdlibUnittest
import StdlibCollectionUnittest import StdlibCollectionUnittest
extension MinimalEquatableValue : Hashable { extension MinimalEquatableValue : Hashable {
public var hashValue: Int { public func hash(into hasher: inout Hasher) {
return value hasher.combine(value)
} }
} }

View File

@@ -10,8 +10,8 @@ class TestHashableBase : Hashable {
self.value = value self.value = value
self.identity = identity self.identity = identity
} }
var hashValue: Int { func hash(into hasher: inout Hasher) {
return value hasher.combine(value)
} }
static func == ( static func == (
lhs: TestHashableBase, lhs: TestHashableBase,