# \[Second Review\] SE-0427: Noncopyable Generics

**URL:** <https://forums.swift.org/t/second-review-se-0427-noncopyable-generics/72881>\
**Category:** Proposal Reviews\
**Created:** [July 2, 2024, 1:41am UTC](https://forums.swift.org/t/second-review-se-0427-noncopyable-generics/72881 "2024-07-02T01:41:26Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![lorentey](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lorentey/32/1299_2.png) [@lorentey](https://forums.swift.org/u/lorentey)\
**Post date:** [July 3, 2024, 1:38am UTC](https://forums.swift.org/t/second-review-se-0427-noncopyable-generics/72881/3 "2024-07-03T01:38:48Z")

</div>

> [@kavon](#):
>
> Looking towards the future where we have a `~Escapable`, we will end up with this situation:
> 
> ```swift
> extension Optional: Copyable where Wrapped: Copyable {}
> extension Optional: Escapable where Wrapped: Escapable {}
> extension Optional: Sendable where Wrapped: ~Copyable & ~Escapable & Sendable {}
> extension Optional: BitwiseCopyable where Wrapped: BitwiseCopyable { }
> 
> ```
> 
> Notice that we do not have to explicitly opt-out of `Escapable` on the `Wrapped` parameter for a conditional Copyable conformance, yet we need to do so for the `Sendable` conformance so that the conformance only requires `Sendable`.

This is greatly bothering me, as it feels like we somehow ended up with rules that are opposite to what the LSG asked for in [their review notes](https://forums.swift.org/t/returned-for-revision-se-0427-noncopyable-generics/72039):

> - Inference of `Copyable` requirements on conditional conformances to `Copyable` is confusing; requirements in this case should be made explicit.

The proposal was updated to reflect this:

> We do this by declaring a _conditional conformance_:
> 
> ```swift
> extension List: Copyable where T: Copyable {}
> 
> ```
> 
> Note that the `where` clause needs to be written, because a conformance to  
> `Copyable` declared in an extension does _not_ automatically add any other  
> requirements, unlike other extensions.

This is all very good. The rules as described make for eminently readable code, as we have to explicitly spell out what we mean. These variants are both hard errors:

```swift
extension Optional: Copyable where Wrapped: ~Copyable {}
// error: cannot suppress '~Copyable' on generic parameter 'Wrapped' defined in outer scope
// error: generic enum 'Optional' required to be 'Copyable' but is marked with '~Copyable'
// error: associated value 'some' of 'Copyable'-conforming generic enum 'Optional' has non-Copyable type 'Wrapped'

extension Optional: Copyable {}
// error: generic enum 'Optional' required to be 'Copyable' but is marked with '~Copyable'
// error: associated value 'some' of 'Copyable'-conforming generic enum 'Optional' has non-Copyable type 'Wrapped'

```

All seems well on the release/6.0 branch. We only have a single one of these suppressible quasi-protocols (`Copyable`), and there appears to be only one way to spell conditional conformances to them, by explicitly spelling things out. We don't need to change anything there, and I think SE-0427 can be considered fully implemented there.

* * *

However, on `main`, we also (provisionally) have a second suppressible quasi-protocol, [`Escapable`](https://forums.swift.org/t/pitch-non-escapable-types-and-lifetime-dependency/69865). I think the addition of this second protocol has uncovered an inconsistency in the current implementation, and this will need to be fixed. (On `main` only, as it only matters there.)

When I go and relax the escapability requirement on `Optional`, the meaning of the conditional `Copyable` conformance syntax suddenly changes in an unexpected way:

```swift
enum Optional<Wrapped: ~Copyable & ~Escapable>: 
  ~Copyable, ~Escapable 
{ ... }

extension Optional: Copyable 
where Wrapped: Copyable {}

extension Optional: Sendable 
where Wrapped: Sendable & ~Copyable {}

```

I've grown to assume that for generic type parameters, the omission of an explicit requirement on one of these suppressible protocols means an implicit positive conformance -- so I was very much surprised to find that their actual meaning is:

```swift
extension Optional: Copyable 
where Wrapped: Copyable & ~Escapable {} // !?

extension Optional: Sendable 
where Wrapped: Sendable & ~Copyable & Escapable {} // OK!

```

Additionally, I cannot even avoid the confusion by spelling out precisely what I mean, as the above code produces the following error on the `Copyable` conformance declaration:

```swift
error: cannot suppress '~Escapable' on generic parameter 'Wrapped' defined in outer scope

```

I think this goes directly against the spirit of the LSG's request -- the review notes ask that "requirements in this case should be made explicit", but here we currently force them to remain implicit (and we also use a default that's inconsistent with the regular case).

I'd very strongly prefer if we required all conditional conformances to a suppressible protocol to explicitly spell out what their requirements are for _all such protocols that the type suppressed on its original declaration_.

```swift
extension Optional: Copyable where Wrapped: Copyable {}
// error: Hey dummy, you forgot to specify what you want for `Escapable`

extension Optional: Copyable where Wrapped: Copyable & ~Escapable {}
// Should be OK

extension Optional: Copyable where Wrapped: Copyable & Escapable {}
// Should also be OK

```

(The diagnostic would also make sense to be a warning rather than a hard error, although there is no source compatibility concern here. Ideally it would come with fix-its to help resolving it.)

This does not need to affect SE-0427, as we only have `Copyable` there; but I think it should be part of the `~Escapable` proposal -- the implicit default choice is misleading/confusing in this context, and we should rather be forcing developers to make an explicit choice.

---

_[View the full topic](https://forums.swift.org/t/second-review-se-0427-noncopyable-generics/72881)._
