Skip to content

Commit 67852ed

Browse files
authored
Merge pull request #16066 from lorentey/better-hash-tests
[stdlib] Review & update hash testing to use Hasher's new features
2 parents 672433c + 6984782 commit 67852ed

File tree

9 files changed

+372
-171
lines changed

9 files changed

+372
-171
lines changed

stdlib/private/StdlibUnittest/MinimalTypes.swift

Lines changed: 142 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ public struct MinimalEquatableValue : Equatable {
5151
self.value = value
5252
self.identity = identity
5353
}
54-
}
55-
public func == (
56-
lhs: MinimalEquatableValue,
57-
rhs: MinimalEquatableValue
58-
) -> Bool {
59-
MinimalEquatableValue.timesEqualEqualWasCalled += 1
60-
return MinimalEquatableValue.equalImpl.value(lhs.value, rhs.value)
54+
55+
public static func == (
56+
lhs: MinimalEquatableValue,
57+
rhs: MinimalEquatableValue
58+
) -> Bool {
59+
MinimalEquatableValue.timesEqualEqualWasCalled += 1
60+
return MinimalEquatableValue.equalImpl.value(lhs.value, rhs.value)
61+
}
6162
}
6263

6364
/// A type that conforms only to `Equatable` and `Comparable`.
@@ -85,22 +86,22 @@ public struct MinimalComparableValue : Equatable, Comparable {
8586
self.value = value
8687
self.identity = identity
8788
}
88-
}
8989

90-
public func == (
91-
lhs: MinimalComparableValue,
92-
rhs: MinimalComparableValue
93-
) -> Bool {
94-
MinimalComparableValue.timesEqualEqualWasCalled.value += 1
95-
return MinimalComparableValue.equalImpl.value(lhs.value, rhs.value)
96-
}
90+
public static func == (
91+
lhs: MinimalComparableValue,
92+
rhs: MinimalComparableValue
93+
) -> Bool {
94+
MinimalComparableValue.timesEqualEqualWasCalled.value += 1
95+
return MinimalComparableValue.equalImpl.value(lhs.value, rhs.value)
96+
}
9797

98-
public func < (
99-
lhs: MinimalComparableValue,
100-
rhs: MinimalComparableValue
101-
) -> Bool {
102-
MinimalComparableValue.timesLessWasCalled.value += 1
103-
return MinimalComparableValue.lessImpl.value(lhs.value, rhs.value)
98+
public static func < (
99+
lhs: MinimalComparableValue,
100+
rhs: MinimalComparableValue
101+
) -> Bool {
102+
MinimalComparableValue.timesLessWasCalled.value += 1
103+
return MinimalComparableValue.lessImpl.value(lhs.value, rhs.value)
104+
}
104105
}
105106

106107

@@ -110,12 +111,12 @@ public func < (
110111
/// other conformances.
111112
public struct MinimalHashableValue : Equatable, Hashable {
112113
public static var timesEqualEqualWasCalled: Int = 0
113-
public static var timesHashValueWasCalled: Int = 0
114+
public static var timesHashIntoWasCalled: Int = 0
114115

115116
public static var equalImpl =
116117
ResettableValue<(Int, Int) -> Bool>({ $0 == $1 })
117-
public static var hashValueImpl =
118-
ResettableValue<(Int) -> Int>({ $0.hashValue })
118+
public static var hashIntoImpl =
119+
ResettableValue<(Int, inout _Hasher) -> Void>({ $1.combine($0) })
119120

120121
public var value: Int
121122
public var identity: Int
@@ -130,18 +131,30 @@ public struct MinimalHashableValue : Equatable, Hashable {
130131
self.identity = identity
131132
}
132133

134+
public static func ==(
135+
lhs: MinimalHashableValue,
136+
rhs: MinimalHashableValue
137+
) -> Bool {
138+
MinimalHashableValue.timesEqualEqualWasCalled += 1
139+
return MinimalHashableValue.equalImpl.value(lhs.value, rhs.value)
140+
}
141+
133142
public var hashValue: Int {
134-
MinimalHashableValue.timesHashValueWasCalled += 1
135-
return MinimalHashableValue.hashValueImpl.value(value)
143+
var hasher = _Hasher()
144+
hasher.combine(self)
145+
return hasher.finalize()
146+
}
147+
148+
public func _hash(into hasher: inout _Hasher) {
149+
MinimalHashableValue.timesHashIntoWasCalled += 1
150+
MinimalHashableValue.hashIntoImpl.value(value, &hasher)
136151
}
137152
}
138153

139-
public func == (
140-
lhs: MinimalHashableValue,
141-
rhs: MinimalHashableValue
142-
) -> Bool {
143-
MinimalHashableValue.timesEqualEqualWasCalled += 1
144-
return MinimalHashableValue.equalImpl.value(lhs.value, rhs.value)
154+
extension MinimalHashableValue: CustomStringConvertible {
155+
public var description: String {
156+
return "MinimalHashableValue(value: \(value), identity: \(identity))"
157+
}
145158
}
146159

147160

@@ -151,12 +164,12 @@ public func == (
151164
/// other conformances.
152165
public class MinimalHashableClass : Equatable, Hashable {
153166
public static var timesEqualEqualWasCalled: Int = 0
154-
public static var timesHashValueWasCalled: Int = 0
167+
public static var timesHashIntoWasCalled: Int = 0
155168

156169
public static var equalImpl =
157170
ResettableValue<(Int, Int) -> Bool>({ $0 == $1 })
158-
public static var hashValueImpl =
159-
ResettableValue<(Int) -> Int>({ $0.hashValue })
171+
public static var hashIntoImpl =
172+
ResettableValue<(Int, inout _Hasher) -> Void>({ $1.combine($0) })
160173

161174
public var value: Int
162175
public var identity: Int
@@ -171,29 +184,45 @@ public class MinimalHashableClass : Equatable, Hashable {
171184
self.identity = identity
172185
}
173186

187+
public static func == (
188+
lhs: MinimalHashableClass,
189+
rhs: MinimalHashableClass
190+
) -> Bool {
191+
MinimalHashableClass.timesEqualEqualWasCalled += 1
192+
return MinimalHashableClass.equalImpl.value(lhs.value, rhs.value)
193+
}
194+
174195
public var hashValue: Int {
175-
MinimalHashableClass.timesHashValueWasCalled += 1
176-
return MinimalHashableClass.hashValueImpl.value(value)
196+
var hasher = _Hasher()
197+
hasher.combine(self)
198+
return hasher.finalize()
199+
}
200+
201+
public func _hash(into hasher: inout _Hasher) {
202+
MinimalHashableClass.timesHashIntoWasCalled += 1
203+
MinimalHashableClass.hashIntoImpl.value(value, &hasher)
177204
}
178205
}
179206

180-
public func == (
181-
lhs: MinimalHashableClass,
182-
rhs: MinimalHashableClass
183-
) -> Bool {
184-
MinimalHashableClass.timesEqualEqualWasCalled += 1
185-
return MinimalHashableClass.equalImpl.value(lhs.value, rhs.value)
207+
extension MinimalHashableClass: CustomStringConvertible {
208+
public var description: String {
209+
return "MinimalHashableClass(value: \(value), identity: \(identity))"
210+
}
186211
}
187212

188213

189214

190215
public var GenericMinimalHashableValue_timesEqualEqualWasCalled: Int = 0
191-
public var GenericMinimalHashableValue_timesHashValueWasCalled: Int = 0
216+
public var GenericMinimalHashableValue_timesHashIntoWasCalled: Int = 0
192217

193-
public var GenericMinimalHashableValue_equalImpl = ResettableValue<(Any, Any) -> Bool>(
194-
{ _, _ in fatalError("GenericMinimalHashableValue_equalImpl is not set yet"); () })
195-
public var GenericMinimalHashableValue_hashValueImpl = ResettableValue<(Any) -> Int>(
196-
{ _ in fatalError("GenericMinimalHashableValue_hashValueImpl is not set yet"); () })
218+
public var GenericMinimalHashableValue_equalImpl =
219+
ResettableValue<(Any, Any) -> Bool>({ _, _ in
220+
fatalError("GenericMinimalHashableValue_equalImpl is not set yet")
221+
})
222+
public var GenericMinimalHashableValue_hashIntoImpl =
223+
ResettableValue<(Any, inout _Hasher) -> Void>({ _ in
224+
fatalError("GenericMinimalHashableValue_hashIntoImpl is not set yet")
225+
})
197226

198227
/// A type that conforms only to `Equatable` and `Hashable`.
199228
///
@@ -213,28 +242,43 @@ public struct GenericMinimalHashableValue<Wrapped> : Equatable, Hashable {
213242
self.identity = identity
214243
}
215244

245+
public static func == <Wrapped>(
246+
lhs: GenericMinimalHashableValue<Wrapped>,
247+
rhs: GenericMinimalHashableValue<Wrapped>
248+
) -> Bool {
249+
GenericMinimalHashableValue_timesEqualEqualWasCalled += 1
250+
return GenericMinimalHashableValue_equalImpl.value(lhs.value, rhs.value)
251+
}
252+
216253
public var hashValue: Int {
217-
GenericMinimalHashableValue_timesHashValueWasCalled += 1
218-
return GenericMinimalHashableValue_hashValueImpl.value(value)
254+
var hasher = _Hasher()
255+
hasher.combine(self)
256+
return hasher.finalize()
219257
}
220-
}
221258

222-
public func == <Wrapped>(
223-
lhs: GenericMinimalHashableValue<Wrapped>,
224-
rhs: GenericMinimalHashableValue<Wrapped>
225-
) -> Bool {
226-
GenericMinimalHashableValue_timesEqualEqualWasCalled += 1
227-
return GenericMinimalHashableValue_equalImpl.value(lhs.value, rhs.value)
259+
public func _hash(into hasher: inout _Hasher) {
260+
GenericMinimalHashableValue_timesHashIntoWasCalled += 1
261+
GenericMinimalHashableValue_hashIntoImpl.value(value, &hasher)
262+
}
228263
}
229264

265+
extension GenericMinimalHashableValue: CustomStringConvertible {
266+
public var description: String {
267+
return "GenericMinimalHashableValue(value: \(value), identity: \(identity))"
268+
}
269+
}
230270

231271
public var GenericMinimalHashableClass_timesEqualEqualWasCalled: Int = 0
232-
public var GenericMinimalHashableClass_timesHashValueWasCalled: Int = 0
272+
public var GenericMinimalHashableClass_timesHashIntoWasCalled: Int = 0
233273

234-
public var GenericMinimalHashableClass_equalImpl = ResettableValue<(Any, Any) -> Bool>(
235-
{ _, _ in fatalError("GenericMinimalHashableClass_equalImpl is not set yet"); () })
236-
public var GenericMinimalHashableClass_hashValueImpl = ResettableValue<(Any) -> Int>(
237-
{ _ in fatalError("GenericMinimalHashableClass_hashValueImpl is not set yet"); () })
274+
public var GenericMinimalHashableClass_equalImpl =
275+
ResettableValue<(Any, Any) -> Bool>({ _, _ in
276+
fatalError("GenericMinimalHashableClass_equalImpl is not set yet")
277+
})
278+
public var GenericMinimalHashableClass_hashIntoImpl =
279+
ResettableValue<(Any, inout _Hasher) -> Void>({ _ in
280+
fatalError("GenericMinimalHashableClass_hashIntoImpl is not set yet")
281+
})
238282

239283
/// A type that conforms only to `Equatable` and `Hashable`.
240284
///
@@ -254,18 +298,30 @@ public class GenericMinimalHashableClass<Wrapped> : Equatable, Hashable {
254298
self.identity = identity
255299
}
256300

301+
public static func == <Wrapped>(
302+
lhs: GenericMinimalHashableClass<Wrapped>,
303+
rhs: GenericMinimalHashableClass<Wrapped>
304+
) -> Bool {
305+
GenericMinimalHashableClass_timesEqualEqualWasCalled += 1
306+
return GenericMinimalHashableClass_equalImpl.value(lhs.value, rhs.value)
307+
}
308+
257309
public var hashValue: Int {
258-
GenericMinimalHashableClass_timesHashValueWasCalled += 1
259-
return GenericMinimalHashableClass_hashValueImpl.value(value)
310+
var hasher = _Hasher()
311+
hasher.combine(self)
312+
return hasher.finalize()
313+
}
314+
315+
public func _hash(into hasher: inout _Hasher) {
316+
GenericMinimalHashableClass_timesHashIntoWasCalled += 1
317+
GenericMinimalHashableClass_hashIntoImpl.value(value, &hasher)
260318
}
261319
}
262320

263-
public func == <Wrapped>(
264-
lhs: GenericMinimalHashableClass<Wrapped>,
265-
rhs: GenericMinimalHashableClass<Wrapped>
266-
) -> Bool {
267-
GenericMinimalHashableClass_timesEqualEqualWasCalled += 1
268-
return GenericMinimalHashableClass_equalImpl.value(lhs.value, rhs.value)
321+
extension GenericMinimalHashableClass: CustomStringConvertible {
322+
public var description: String {
323+
return "GenericMinimalHashableClass(value: \(value), identity: \(identity))"
324+
}
269325
}
270326

271327

@@ -299,6 +355,22 @@ public struct MinimalStrideableValue : Equatable, Comparable, Strideable {
299355

300356
public typealias Stride = Int
301357

358+
public static func == (
359+
lhs: MinimalStrideableValue,
360+
rhs: MinimalStrideableValue
361+
) -> Bool {
362+
MinimalStrideableValue.timesEqualEqualWasCalled.value += 1
363+
return MinimalStrideableValue.equalImpl.value(lhs.value, rhs.value)
364+
}
365+
366+
public static func < (
367+
lhs: MinimalStrideableValue,
368+
rhs: MinimalStrideableValue
369+
) -> Bool {
370+
MinimalStrideableValue.timesLessWasCalled.value += 1
371+
return MinimalStrideableValue.lessImpl.value(lhs.value, rhs.value)
372+
}
373+
302374
public func distance(to other: MinimalStrideableValue) -> Stride {
303375
MinimalStrideableValue.timesDistanceWasCalled.value += 1
304376
return other.value - self.value
@@ -310,21 +382,6 @@ public struct MinimalStrideableValue : Equatable, Comparable, Strideable {
310382
}
311383
}
312384

313-
public func == (
314-
lhs: MinimalStrideableValue,
315-
rhs: MinimalStrideableValue
316-
) -> Bool {
317-
MinimalStrideableValue.timesEqualEqualWasCalled.value += 1
318-
return MinimalStrideableValue.equalImpl.value(lhs.value, rhs.value)
319-
}
320-
321-
public func < (
322-
lhs: MinimalStrideableValue,
323-
rhs: MinimalStrideableValue
324-
) -> Bool {
325-
MinimalStrideableValue.timesLessWasCalled.value += 1
326-
return MinimalStrideableValue.lessImpl.value(lhs.value, rhs.value)
327-
}
328385

329386
// Local Variables:
330387
// eval: (read-only-mode 1)

0 commit comments

Comments
 (0)