# Noncopyable Generics in Swift: A Code Walkthrough

**URL:** <https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862>\
**Category:** Discussion\
**Tags:** generics, swift-evolution, noncopyable, tutorial\
**Created:** [March 23, 2024, 7:06pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862 "2024-03-23T19:06:16Z")\
**Posts on this page:** 8\
**Page:** 3

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [March 25, 2024, 7:50am UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/42 "2024-03-25T07:50:14Z")

</div>

> [@rvsrvs](#):
>
> got me thinking about [@lorentey 's implementation of the Michael/Scott LockFreeQueue in swift-atomics](https://github.com/apple/swift-atomics/blob/1f2007ef4165432f59f28615c473eb79a844a2af/Tests/AtomicsTests/LockFreeQueue.swift#L41). I'm kind of wondering now if the need for `Node` to be `~Copyable` in the basic `List` and `ManagedAtomic` in the `LockFreeQueue` is not an indicator that we'd like `Atomic` to be capable of something similar.

I suspect the answer is no. I've been playing about with Ben's example to build up a lock-free queue, and the reality is that you don't actually need the atomic to support a non-copyable type: you need it to support a _pointer_ to one. The support here ought to be sufficient.

---

<div class="post-metadata">

**Author:** ![asdf](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@asdf](https://forums.swift.org/u/asdf)\
**Post date:** [March 25, 2024, 11:03am UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/43 "2024-03-25T11:03:00Z")

</div>

is it possible to create `struct Vector<Elem: ~Copyable>: ~Copyable, Sequence` ?  
Does it make sense to conform to both `~Copyable` and `Sequence` ?

---

<div class="post-metadata">

**Author:** ![rvsrvs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rvsrvs/32/5270_2.png) [@rvsrvs](https://forums.swift.org/u/rvsrvs)\
**Post date:** [March 25, 2024, 12:27pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/44 "2024-03-25T12:27:31Z")

</div>

@lukasa, Could you explain more, bc that seems... surprising. Intuitively, I would have thought that pointing at a move-only type was defeating the purpose of having it to begin with.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [March 25, 2024, 12:50pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/45 "2024-03-25T12:50:04Z")

</div>

> Does it make sense to conform to both `~Copyable` and `Sequence`?

`struct Vector<Elem: ~Copyable>: ~Copyable` is _not_ a "conformance to `~Copyable`". There is no such thing as a `~Copyable` protocol to conform to. The constraint says "this struct does not unconditionally conform to Copyable" or even more precisely "the (normally defaulted) Copyable conformance has been suppressed". So the full reading of this is something like "Vector is a struct, generic on a type Elem which cannot be assumed to be Copyable. Vector does not unconditionally conform to Copyable".

Sequence (like all protocols that predate Swift 6.0) refines Copyable, so this does not make sense. Conformance to Sequence requires that Vector be Copyable, and so it must not have its conformance suppressed.

We (the Swift community broadly, and Apple's compiler and standard library teams specifically) are investigating how best to provide collection-like protocols that support types without the Copyable (or Escapable) constraints, but this is more complex than designing the existing (Copyable) collection protocols was, and it's only just recently become possible for people to experiment with nearly-stable tools, so it will take a little bit of experience to figure out what the best patterns are.

---

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [March 25, 2024, 12:50pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/46 "2024-03-25T12:50:57Z")

</div>

> [@rvsrvs](#):
>
> @lukasa, Could you explain more, bc that seems... surprising. Intuitively, I would have thought that pointing at a move-only type was defeating the purpose of having it to begin with.

The insight here is that these two constructions are very similar:

```swift
struct Foo: ~Copyable { }

class Bar {
    var f: Foo
}

let b1 = UnsafeMutablePointer<Foo>.allocate(capacity: 1).initialize(to: Foo())
let b2 = Bar(f: Foo())

```

In both of these cases there is a heap allocated box that stores a `Foo`. In both cases we have a reference to that box: for b1, the reference is the pointer, for b2, the reference is the class.

Importantly, nothing prevents you copying the _reference_: you can have as many copies of that as you want. You can also _borrow_ that reference all you want: accessing the noncopyable type through its memory location is sound.

The non-copyable type defenses prevent you doing the thing you _aren't_ allowed to do, which is to copy the type out of the box. This defense works in both cases.

---

<div class="post-metadata">

**Author:** ![asdf](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@asdf](https://forums.swift.org/u/asdf)\
**Post date:** [March 25, 2024, 1:25pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/47 "2024-03-25T13:25:39Z")

</div>

> Sequence (like all protocols that predate Swift 6.0) refines Copyable, so this does not make sense. Conformance to Sequence requires that Vector be Copyable, and so it must not have its conformance suppressed.

According to docs:

> The `Sequence` protocol makes no requirement on conforming types regarding whether they will be destructively consumed by iteration.  
> ([Sequence | Apple Developer Documentation](https://developer.apple.com/documentation/swift/sequence#Repeated-Access))

How to understand it?

---

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [March 25, 2024, 1:33pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/48 "2024-03-25T13:33:55Z")

</div>

It would be possible to retroactively change `Sequence` to be marked `~Copyable` and still fulfill the letter of this, yes. `makeIterator()` is already marked `__consuming` (the precursor to `consuming` used by the standard library). Iteration of a non-copyable sequence would therefore consume it.

The trouble is, this would be very annoying for a lot of cases. People assume that you can iterate a sequence more than once, non-destructively, and indeed you can in most cases. Like our list example – the whole point of `forEach` instead of `pop` in the example above is that you can do it non-destructively.

More design is needed here. Probably alongside further language features, like the ability to have borrowed references to elements. As it happens, the way sequences and collections work is sub-optimal for a bunch of other reasons (including being vague on the question of multi-pass), and that should probably be tackled together with this question.

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [March 25, 2024, 1:37pm UTC](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862/49 "2024-03-25T13:37:15Z")

</div>

> [@ben-cohen](#):
>
> It would be possible to retroactively change `Sequence` to be marked `~Copyable` and still fulfill the letter of this, yes.

However it’s worth pointing out we cannot make the `Element` associated type be ~Copyable without a source break.

[Previous page](https://forums.swift.org/t/noncopyable-generics-in-swift-a-code-walkthrough/70862.md?page=2)
