When Set/Dictionary is nested in another Set, the boundaries of the nested collections weren’t correctly delineated in commutative hashing.
For example, these Sets all hashed the same:
[[1, 2], [3, 4]]
[[1, 3], [2, 4]]
[[1, 4], [2, 3]]
Hash collisions could thus be systematically generated.
To fix this, remove collection-level support for one-shot hashing and revert to the previous method of generating hash values. (Set is still able to support one-shot hashing for its members, though.)
The new _rawHashValue(seed:) requirement allows stdlib types to specialize their hashing when they’re hashed on their own (i.e., not as a component of some composite type).
This makes it possible to get rid of discriminator/terminator values and to eliminate most of Hasher’s resiliency overhead, leading to a measurable speedup, especially for tiny keys.
As noted in the proposal’s revision, this allows us to get rid of finalization checks, improves API robustness, and paves the way for making Hasher move-only in the future.
This implements the new last(where:), and lastIndex(of/where:) methods as
extensions on `BidirectionalCollection`, which partially implements SE-204.
The protocol requirements for `Sequence` and `Collection` as described
in the proposal need to wait until there's a solution for picking up the
specialized versions in types that conditionally conform to `BidirectionalCollection`.
Avoid describing the exact algorithm that these collections use to allocate storage. (It is a private implementation detail that we want to be able to change.)
rdar://problem/36619317
When a duplicate key is found during rehashing, it is usually either because a key was mutated after insertion, or because the dictionary itself was mutated from multiple threads at the same time.
Both of these are serious programmer errors. Promote the sanity check for duplicate keys to a full precondition and improve the error message to point out the most probable cause of the failure.
Split HashedCollections.swift.gyb into separate Set.swift and Dictionary.swift files, with some common parts going into Hashing.swift.
This is mostly a mechanical change, in preparation of unification of common parts between Set & Dictionary.
rdar://problem/34038727