Skip to content

Commit 85836b8

Browse files
authored
Merge pull request #16176 from lorentey/describe-hashing-changes-4.2
[4.2][SE-0206] Update CHANGELOG.md
2 parents 875d2a1 + db5bdd9 commit 85836b8

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

CHANGELOG.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,73 @@ Swift 5.0
6161
Swift 4.2
6262
---------
6363

64+
* [SE-0206][]
65+
66+
The standard library now uses a high-quality, randomly seeded, universal
67+
hash function, represented by the new public `Hasher` struct.
68+
69+
“Random seeding” varies the result of `hashValue` on each execution of a
70+
Swift program, improving the reliability of the standard library's hashed
71+
collections such as `Set` and `Dictionary`. In particular, random seeding
72+
enables better protection against (accidental or deliberate) hash-flooding
73+
attacks.
74+
75+
This change fulfills a long-standing prophecy in Hashable's documentation:
76+
77+
> Hash values are not guaranteed to be equal across different executions of
78+
> your program. Do not save hash values to use during a future execution.
79+
80+
As a consequence of random seeding, the elements in `Set` and `Dictionary`
81+
values may have a different order on each execution. This may expose some
82+
bugs in existing code that accidentally relies on repeatable ordering.
83+
84+
Additionally, the `Hashable` protocol now includes an extra function
85+
requirement, `hash(into:)`. The new requirement is designed to be much
86+
easier to implement than the old `hashValue` property, and it generally
87+
provides better hashing. To implement `hash(into:)`, simply feed the exact
88+
same components of your type that you compare in `Equatable`'s `==`
89+
implementation to the supplied `Hasher`:
90+
91+
```swift
92+
struct Foo: Hashable {
93+
var a: String?
94+
var b: [Int]
95+
var c: [String: Int]
96+
97+
static func ==(lhs: Foo, rhs: Foo) -> Bool {
98+
return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c
99+
}
100+
101+
func hash(into hasher: inout Hasher) {
102+
hasher.combine(a)
103+
hasher.combine(b)
104+
hasher.combine(c)
105+
}
106+
}
107+
```
108+
109+
Automatic synthesis for `Hashable` ([SE-0185]) has been updated to generate
110+
`hash(into:)` implementations. For example, the `==` and `hash(into:)`
111+
implementations above are equivalent to the ones synthesized by the
112+
compiler, and can be removed without changing the meaning of the code.
113+
114+
Synthesis has also been extended to support deriving `hashValue` from
115+
`hash(into:)`, and vice versa. Therefore, code that only implements
116+
`hashValue` continues to work in Swift 4.2. This new compiler functionality
117+
works for all types that can implement `Hashable`, including classes.
118+
119+
Note that these changes don't affect Foundation's hashing interface. Classes
120+
that subclass `NSObject` should override the `hash` property, like before.
121+
122+
In certain controlled environments, such as while running particular tests,
123+
it may be helpful to selectively disable hash seed randomization, so that
124+
hash values and the order of elements in `Set`/`Dictionary` values remain
125+
consistent across executions. You can disable hash seed randomization by
126+
defining the environment variable `SWIFT_DETERMINISTIC_HASHING` with the
127+
value of `1`. The Swift runtime looks at this variable during process
128+
startup and, if it is defined, replaces the random seed with a constant
129+
value.
130+
64131
* [SR-106][]
65132

66133
The behavior of `.description` and `.debugDescription` for floating-point
@@ -6989,6 +7056,7 @@ Swift 1.0
69897056
[SE-0197]: <https://github.com/apple/swift-evolution/blob/master/proposals/0197-remove-where.md>
69907057
[SE-0198]: <https://github.com/apple/swift-evolution/blob/master/proposals/0198-playground-quicklook-api-revamp.md>
69917058
[SE-0199]: <https://github.com/apple/swift-evolution/blob/master/proposals/0199-bool-toggle.md>
7059+
[SE-0206]: <https://github.com/apple/swift-evolution/blob/master/proposals/0206-hashable-enhancements.md>
69927060

69937061
[SR-106]: <https://bugs.swift.org/browse/SR-106>
69947062
[SR-419]: <https://bugs.swift.org/browse/SR-419>

0 commit comments

Comments
 (0)