* Update std lib to Swift 5.0
* Disable Unicode.* warnings for now
* Slow path to resiliently handle the case where an unknown rounding rule is passed
* Remove resilience from Encoding/DecodingError (which should only happen on slow paths anyway)
* internal typealiases now need @usableFromInline
* Force inlining on Array._owner.get
This allows Set’s internal types not to define Key, Value, SequenceElement & SequenceElementWithoutLabels typealiases.
Splitting the protocol on the mutable/immutable axis allows us to remove some obsolete method definitions.
AnyHashable has numerous edge cases where two AnyHashable values compare equal but produce different hashes. This breaks Set and Dictionary invariants and can cause unexpected behavior and/or traps. This change overhauls AnyHashable's implementation to fix these edge cases, hopefully without introducing new issues.
- Fix transitivity of ==. Previously, comparisons involving AnyHashable values with Objective-C provenance were handled specially, breaking Equatable:
let a = (42 as Int as AnyHashable)
let b = (42 as NSNumber as AnyHashable)
let c = (42 as Double as AnyHashable)
a == b // true
b == c // true
a == c // was false(!), now true
let d = ("foo" as AnyHashable)
let e = ("foo" as NSString as AnyHashable)
let f = ("foo" as NSString as NSAttributedStringKey as AnyHashable)
d == e // true
e == f // true
d == f // was false(!), now true
- Fix Hashable conformance for numeric types boxed into AnyHashable:
b == c // true
b.hashValue == c.hashValue // was false(!), now true
Fixing this required adding a custom AnyHashable box for all standard integer and floating point types. The custom box was needed to ensure that two AnyHashables containing the same number compare equal and hash the same way, no matter what their original type was. (This behavior is required to ensure consistency with NSNumber, which has not been preserving types since SE-0170.
- Add custom AnyHashable representations for Arrays, Sets and Dictionaries, so that when they contain numeric types, they hash correctly under the new rules above.
- Remove AnyHashable._usedCustomRepresentation. The provenance of a value should not affect its behavior.
- Allow AnyHashable values to be downcasted into compatible types more often.
- Forward _rawHashValue(seed:) to AnyHashable box. This fixes AnyHashable hashing for types that customize single-shot hashing.
https://bugs.swift.org/browse/SR-7496
rdar://problem/39648819
As a general rule, it is safe to mark the implementation of hash(into:) and _rawHashValue(seed:) for @_fixed_layout structs as inlinable.
However, some structs (like String guts, Character, KeyPath-related types) have complicated enough hashing that it seems counterproductive to inline them. Mark these with @effects(releasenone) instead.
This includes various revisions to the APIs landing in Swift 4.2, including:
- Random and other randomness APIs
- Hashable changes
- MemoryLayout.offset(of:)
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.
Aggressively remove all `@inlinable` from any function that's
`@inline(never)` to see the impact.
`@inlinable @inline(never)` is a potential code smell. While it might
expose some optimization and specialization opportunities to the
optimizer, it's most commonly a sign that more thought is needed.
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