The LSG has decided to acceptUniqueArrayin principle, but not RigidArray, and to place UniqueArray in the Swift module rather than introducing a new Containers module now.
The LSG believes that UniqueArray is the type that most users will want to reach for most of the time when working with non-copyable containers, and that the value of RigidArray is less clear. Any non-trapping use of RigidArray can be replaced with UniqueArray with no change to program semantics. Further development of non-copyable containers and protocols may show the need for RigidArray more clearly, but at this point in time the LSG is not convinced that it is needed.
Because we see UniqueArray as so fundamental, we believe that it belongs in the Swift module.
A note on reallocate(capacity:)
This proposed function is the one exception to the acceptance. It received only minimal attention in the initial review, and unlike most of the API on UniqueArray this operation is mostly unprecedented in the standard library and packages. Much of the API providing similar functionality in other languages and libraries is not great. We want to have more confidence in this API, so I am going to create a separate thread to discuss it in detail.
Thank you for your participation in Swift evolution.
– Steve Canon
Will there be separate proposals for UniqueSet and UniqueDictionary? I believe that if we are introducing a unique variant of Array, we should do the same for the other two primary collection types, Set and Dictionary. Otherwise, IMO, we introduce unnecessary inconsistency and frustration. What is the plan or rationale against introducing UniqueSet and UniqueDictionary simultaneously with UniqueArray?
All three are important, but UniqueArray is much more fundamental and immediately necessary (at least for the use cases I've been looking at). It also gives us a simpler surface area to discuss fundamental design questions of non-copyable containers and allows subsequent proposals to focus on the details specific to Set/Dictionary.
I'm interested to understand the rationale behind choosing the Unique prefix for these new collections (UniqueArray and presumably future types like UniqueDeque). Since this prefix will likely become standard across all upcoming non‑copyable containers, the naming choice carries significant weight.
A few considerations:
Owned directly aligns with Swift's ownership model (consuming, borrowing, ~Copyable, Ownership manifesto document). A developer familiar with these concepts would immediately recognise that an OwnedArray cannot be copied – it must be moved. This is precisely the semantic we need and it uses terminology already established in the language.
Exclusive conveys that the container has exclusive access to its storage (no sharing) and is exclusively owned itself.
Unique is already used in other contexts which might cause confusion about whether it guarantees uniqueness elements, uniqueness of instance or some other kind of uniqueness.
We already have concept of "uniquely referenced" memory buffers – the isUniquelyReferenced() function and #Unique in SwiftData. Naming a new low-level array Unique might inadvertently carry this baggage, implying a focus on reference counting rather than ownership. The proposed UniqueArray would introduce another meaning for Unique in the Swift ecosystem and Unique prefix make a confusing precedent for future containers.
The term "unique" in isUniquelyReferenced() is about runtime reference‑counting checks – a concept that applies to copyable types with CoW. UniqueArray is non‑copyable so reference‑counting uniqueness is irrelevant. By reusing the same prefix we risk conflating two completely different mechanisms: ownership (compile‑time, non‑copyable) and buffer uniqueness (runtime, copy‑on‑write). This is likely to confuse Swift developers.
"Unique" is not a term currently used for a unique ownership system. The ownership manifesto consistently uses owned, consuming and borrowing. Introducing Unique as a prefix for ownership‑based containers breaks that consistency.
Could you elaborate on why Unique was chosen over these alternatives?
It’s actually very good that the term is distinct from these, because these concepts all still apply to UniqueArray values. In fact, since it’s a non-copyable type, needing to borrow or consume explicitly is more necessary than otherwise.
I’m not sure why you’re drawing such a strong line between these. There was even an evolution direction we explored in this review where UniqueArray would use exactly Array’s array buffer representation precisely so that you could extract a UniqueArray from an Array as a type-safe representation of an array buffer that’s known to be uniquely referenced. Ultimately, we decided not to force the overheads that would’ve implied onto this type, but I personally think it’s still very useful and something we should pursue as a separate type.