[Swift Collections 1.1.0] Explicit Sendable conformances

To resolve issue #166, I propose to add the following explicit Sendable conformances to the collections package.

The public types exported by Swift Collections are all supposed to provide value semantics as long as the underlying element types (Element, Key, Value) are values. Consequently, most of the Sendable conformances below are conditional on the corresponding generic parameter being Sendable.

This is emulating the Swift Standard Library's existing Sendable conformances for its own standard collection types (Array, Set, Dictionary, String & their iterators, views, etc.). Like in the stdlib, these Sendable conformances come for free -- the existing copy-on-write optimization (based on isKnownUniquelyReferenced) already ensures that standalone copies of these types are safely sharable across actor boundaries.

My hope is therefore that these conformances will be straightforward and relatively free of controversies. (Please do prove me wrong! :stuck_out_tongue_winking_eye:)

extension BitArray: Sendable {}

extension BitSet: Sendable {}
extension BitSet.Iterator: Sendable {}
extension BitSet.Index: Sendable {}
extension BitSet.Counted: Sendable {}

extension Deque: @unchecked Sendable where Element: Sendable {}
extension Deque.Iterator: Sendable where Element: Sendable {}

extension Heap: Sendable where Element: Sendable {}

extension OrderedSet: @unchecked Sendable where Element: Sendable {}
extension OrderedSet.SubSequence: Sendable where Element: Sendable {}
extension OrderedSet.UnorderedView: Sendable where Element: Sendable {}
//extension OrderedSet._UnstableInternals: Sendable where Element: Sendable {}

extension OrderedDictionary: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension OrderedDictionary.Iterator: Sendable where Key: Sendable, Value: Sendable {}
extension OrderedDictionary.Values: Sendable where Key: Sendable, Value: Sendable {}
extension OrderedDictionary.Elements: Sendable where Key: Sendable, Value: Sendable {}
extension OrderedDictionary.Elements.SubSequence: Sendable where Key: Sendable, Value: Sendable {}
extension OrderedDictionary.Elements.SubSequence.Iterator: Sendable where Key: Sendable, Value: Sendable {}

extension PersistentSet: @unchecked Sendable where Element: Sendable {}
extension PersistentSet.Iterator: @unchecked Sendable where Element: Sendable {}
extension PersistentSet.Index: @unchecked Sendable where Element: Sendable {}

extension PersistentDictionary: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Iterator: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Index: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Keys: Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Keys.Iterator: Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Values: Sendable where Key: Sendable, Value: Sendable {}
extension PersistentDictionary.Values.Iterator: Sendable where Key: Sendable, Value: Sendable {}

// The ones below are provisional -- SortedSet/SortedDictionary aren't quite ready yet, 
// and they may or may not make it into the 1.1.0 release.
extension SortedSet: @unchecked Sendable where Element: Sendable {}
extension SortedSet.Iterator: @unchecked Sendable where Element: Sendable {}
extension SortedSet.Index: @unchecked Sendable where Element: Sendable {}
extension SortedSet.SubSequence: @unchecked Sendable where Element: Sendable {}
extension SortedSet.SubSequence.Iterator: @unchecked Sendable where Element: Sendable {}

extension SortedDictionary: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Iterator: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Index: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.SubSequence: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.SubSequence.Iterator: @unchecked Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Keys: Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Keys.Iterator: Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Values: Sendable where Key: Sendable, Value: Sendable {}
extension SortedDictionary.Values.Iterator: Sendable where Key: Sendable, Value: Sendable {}

As noted, SortedSet and SortedDictionary aren't ready for production use yet, and they may or may not make it into the 1.1.0 release. Accordingly, their Sendable conformances will ship in the first Collections release that ships these types.

9 Likes

These all look pretty reasonable and are in-line with my experience with migration of other types with Sendability.

4 Likes

I merged the PR implementing these conformances to the release/1.1 branch. The discussion remains open -- if anyone finds a reason to object to these, please raise it!

1 Like