# SE-0319: Never as Identifiable

**URL:** <https://forums.swift.org/t/se-0319-never-as-identifiable/50246>\
**Category:** Proposal Reviews\
**Created:** [July 6, 2021, 9:35pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246 "2021-07-06T21:35:10Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomerd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tomerd/32/3402_2.png) [@tomerd](https://forums.swift.org/u/tomerd)\
**Post date:** [July 6, 2021, 9:35pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/1 "2021-07-06T21:35:10Z")

</div>

The review of [SE-0319: Never as Identifiable](https://github.com/apple/swift-evolution/blob/main/proposals/0319-never-identifiable.md), begins now and runs through July 13, 2021.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager or direct message in the Swift forums).

## What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

- What is your evaluation of the proposal?
- Is the problem being addressed significant enough to warrant a change to Swift?
- Does this proposal fit well with the feel and direction of Swift?
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thank you for helping improve the Swift programming language and ecosystem.

Tom Doron  
Review Manager

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [July 6, 2021, 9:54pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/2 "2021-07-06T21:54:01Z")

</div>

Hello, thanks for this proposal.

> As the warning notes, the new conformance will be used to satisfy the protocol requirement. This difference shouldn't present an observable difference given that an instance of `Never` cannot be constructed.

There is a difference if an existing module declares an `ID` type which is not `Never`. The proposal, as written, would break such existing code.

IIRC, previous proposals of the same kind did preserve existing conformances instead of replacing them with the one of the standard library. Maybe someone has a better recollection than mine, and could point to such a precedent?

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [July 6, 2021, 10:40pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/3 "2021-07-06T22:40:12Z")

</div>

I am +1 on this proposal, it is straight-forward.

However, this continues to highlight a significant design point we need to look at: Never should implicitly conform to a bunch of protocols. Having one-off swift evolution proposals for each of them doesn't really make sense, we should have a systematic approach.

-Chris

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [July 7, 2021, 8:08am UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/4 "2021-07-07T08:08:09Z")

</div>

I support this change, no problem 👍

But I guess I'll ask the elephant in the room question -- why not look into making `Never` a true bottom type? It always seemed weird to me that Swift lacked a true bottom type and `Never` seemed like the natural candidate for it.

This does not block the current proposal from being accepted, just wanted to see if there's any thoughts we can share here?

---

<div class="post-metadata">

**Author:** ![ricketson](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ricketson/32/8365_2.png) [@ricketson](https://forums.swift.org/u/ricketson)\
**Post date:** [July 7, 2021, 3:44pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/5 "2021-07-07T15:44:04Z")

</div>

The [acceptance rationale for SE-0215](https://forums.swift.org/t/se-0215-conform-never-to-equatable-and-hashable/13586/45) provides some extra info:

> - `Never` should become a blessed bottom type in the language. This matches with semantics in other languages and its intended role in Swift.
> 
> With respect to the latter, the Core Team discussed what `Never` being a bottom type actually meant. From that discussion we reached the following conclusions:
> 
> - Semantically, as a bottom type, it would mean that `Never` should be implicitly convertible to any other type. This composes well in the type system because of the fact that instances of `Never` cannot be instantiated.
> - However, being a bottom type does _not_ imply that `Never` should implicitly conform to all protocols. Instead, convenient protocol conformances for `Never` should be added as deemed useful or necessary.
> 
> There are various details to suss out with making `Never` a bottom type, and thus making it a bottom type would be served by a _separate and well-considered proposal_ . It is the opinion of the Core Team that making `Never` a bottom type would be separate from it conforming to all protocols, and thus the motivation of this particular proposal and the particular problems it addresses stands on its own.
> 
> With respect to protocol conformances, the Core Team felt the language has clearly moved in a direction where explicit protocol conformance is fundamental to the language model. The compiler has grown affordances to make the implementation of protocol conformances easy in many cases (e.g., synthesized implementations of `Hashable` ) but that the _explicit_ protocol conformance is quite important. Adding rules for implicit protocol conformances — something that has been considered in Swift’s history — ends up adding real complexity to the language and its implementation that can be hard to reason about by a user as well as by the language implementation.

(which is not the say that that's the end of the discussion, but just the latest official statement from the Core Team. Note of course the explicit invitation for a "separate and well-considered proposal" to discuss further)

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [July 8, 2021, 3:06pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/6 "2021-07-08T15:06:16Z")

</div>

> [@Chris\_Lattner3](#):
>
> Having one-off swift evolution proposals for each of them doesn't really make sense, we should have a systematic approach.

Perhaps that approach should start with a list of all protocols in the Swift Standard Library and solicit any objections to conforming `Never` to each of them?

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [July 8, 2021, 4:59pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/7 "2021-07-08T16:59:16Z")

</div>

> [@ricketson](#):
>
> With respect to protocol conformances, the Core Team felt the language has clearly moved in a direction where explicit protocol conformance is fundamental to the language model. The compiler has grown affordances to make the implementation of protocol conformances easy in many cases (e.g., synthesized implementations of `Hashable` ) but that the _explicit_ protocol conformance is quite important. Adding rules for implicit protocol conformances — something that has been considered in Swift’s history — ends up adding real complexity to the language and its implementation that can be hard to reason about by a user as well as by the language implementation.

I remember that remark. It would be helpful to hear a little more detail about this reasoning, which I’m afraid entirely eludes me.

The bottom type is inherently a unique beast; there can be only one. And in my naïveté, it seems to me that this unique special case can and should conform to all protocols:

From the compiler’s point of view, I would assume that since no runtime values ever belong to it, it does not need a witness table or any other kind of runtime support other than a metatype. In type checking, it would form a unique “always true” special case, one that does not require any sort of more general implicit conformance mechanism.

From the language user’s point of view, I’m hard-pressed to think of any logical reason why any protocol would _not_ want `Never` to conform to it.

I’m sure there’s an excellent rationale here! It just eludes me. As it stands, [Chris’s](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/3) and [Konrad’s](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/4) remarks echo my sentiments exactly:

If making `Never` a _true_ bottom type, including all protocols, is off the table, then at least this:

> [@toph42](#):
>
> Perhaps that approach should start with a list of all protocols in the Swift Standard Library and solicit any objections to conforming `Never` to each of them?

…seems like the minimum sensible approach.

---

<div class="post-metadata">

**Author:** ![mtsrodrigues](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mtsrodrigues/32/34169_2.png) [@mtsrodrigues](https://forums.swift.org/u/mtsrodrigues)\
**Post date:** [July 8, 2021, 6:35pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/8 "2021-07-08T18:35:23Z")

</div>

> [@toph42](#):
>
> Perhaps that approach should start with a list of all protocols in the Swift Standard Library and solicit any objections to conforming `Never` to each of them?

[AdditiveArithmetic](https://developer.apple.com/documentation/swift/additivearithmetic)  
[BidirectionalCollection](https://developer.apple.com/documentation/swift/bidirectionalcollection)  
[BinaryFloatingPoint](https://developer.apple.com/documentation/swift/binaryfloatingpoint)  
[BinaryInteger](https://developer.apple.com/documentation/swift/binaryinteger)  
[CVarArg](https://developer.apple.com/documentation/swift/cvararg)  
[CaseIterable](https://developer.apple.com/documentation/swift/caseiterable)  
[CodingKey](https://developer.apple.com/documentation/swift/codingkey)  
[Collection](https://developer.apple.com/documentation/swift/collection)  
[Comparable](https://developer.apple.com/documentation/swift/comparable)  
[CustomDebugStringConvertible](https://developer.apple.com/documentation/swift/customdebugstringconvertible)  
[CustomLeafReflectable](https://developer.apple.com/documentation/swift/customleafreflectable)  
[CustomPlaygroundDisplayConvertible](https://developer.apple.com/documentation/swift/customplaygrounddisplayconvertible)  
[CustomReflectable](https://developer.apple.com/documentation/swift/customreflectable)  
[CustomStringConvertible](https://developer.apple.com/documentation/swift/customstringconvertible)  
[Decodable](https://developer.apple.com/documentation/swift/decodable)  
[Decoder](https://developer.apple.com/documentation/swift/decoder)  
[Encodable](https://developer.apple.com/documentation/swift/encodable)  
[Encoder](https://developer.apple.com/documentation/swift/encoder)  
[Equatable](https://developer.apple.com/documentation/swift/equatable)  
[Error](https://developer.apple.com/documentation/swift/error)  
[ExpressibleByArrayLiteral](https://developer.apple.com/documentation/swift/expressiblebyarrayliteral)  
[ExpressibleByBooleanLiteral](https://developer.apple.com/documentation/swift/expressiblebybooleanliteral)  
[ExpressibleByDictionaryLiteral](https://developer.apple.com/documentation/swift/expressiblebydictionaryliteral)  
[ExpressibleByExtendedGraphemeClusterLiteral](https://developer.apple.com/documentation/swift/expressiblebyextendedgraphemeclusterliteral)  
[ExpressibleByFloatLiteral](https://developer.apple.com/documentation/swift/expressiblebyfloatliteral)  
[ExpressibleByIntegerLiteral](https://developer.apple.com/documentation/swift/expressiblebyintegerliteral)  
[ExpressibleByNilLiteral](https://developer.apple.com/documentation/swift/expressiblebynilliteral)  
[ExpressibleByStringInterpolation](https://developer.apple.com/documentation/swift/expressiblebystringinterpolation)  
[ExpressibleByStringLiteral](https://developer.apple.com/documentation/swift/expressiblebystringliteral)  
[ExpressibleByUnicodeScalarLiteral](https://developer.apple.com/documentation/swift/expressiblebyunicodescalarliteral)  
[FixedWidthInteger](https://developer.apple.com/documentation/swift/fixedwidthinteger)  
[FloatingPoint](https://developer.apple.com/documentation/swift/floatingpoint)  
[Hashable](https://developer.apple.com/documentation/swift/hashable)  
[Identifiable](https://developer.apple.com/documentation/swift/identifiable)  
[IteratorProtocol](https://developer.apple.com/documentation/swift/iteratorprotocol)  
[KeyedDecodingContainerProtocol](https://developer.apple.com/documentation/swift/keyeddecodingcontainerprotocol)  
[KeyedEncodingContainerProtocol](https://developer.apple.com/documentation/swift/keyedencodingcontainerprotocol)  
[LazyCollectionProtocol](https://developer.apple.com/documentation/swift/lazycollectionprotocol)  
[LazySequenceProtocol](https://developer.apple.com/documentation/swift/lazysequenceprotocol)  
[LosslessStringConvertible](https://developer.apple.com/documentation/swift/losslessstringconvertible)  
[MirrorPath](https://developer.apple.com/documentation/swift/mirrorpath)  
[MutableCollection](https://developer.apple.com/documentation/swift/mutablecollection)  
[Numeric](https://developer.apple.com/documentation/swift/numeric)  
[OptionSet](https://developer.apple.com/documentation/swift/optionset)  
[RandomAccessCollection](https://developer.apple.com/documentation/swift/randomaccesscollection)  
[RandomNumberGenerator](https://developer.apple.com/documentation/swift/randomnumbergenerator)  
[RangeExpression](https://developer.apple.com/documentation/swift/rangeexpression)  
[RangeReplaceableCollection](https://developer.apple.com/documentation/swift/rangereplaceablecollection)  
[RawRepresentable](https://developer.apple.com/documentation/swift/rawrepresentable)  
[SIMD](https://developer.apple.com/documentation/swift/simd)  
[SIMDScalar](https://developer.apple.com/documentation/swift/simdscalar)  
[SIMDStorage](https://developer.apple.com/documentation/swift/simdstorage)  
[Sequence](https://developer.apple.com/documentation/swift/sequence)  
[SetAlgebra](https://developer.apple.com/documentation/swift/setalgebra)  
[SignedInteger](https://developer.apple.com/documentation/swift/signedinteger)  
[SignedNumeric](https://developer.apple.com/documentation/swift/signednumeric)  
[SingleValueDecodingContainer](https://developer.apple.com/documentation/swift/singlevaluedecodingcontainer)  
[SingleValueEncodingContainer](https://developer.apple.com/documentation/swift/singlevalueencodingcontainer)  
[Strideable](https://developer.apple.com/documentation/swift/strideable)  
[StringInterpolationProtocol](https://developer.apple.com/documentation/swift/stringinterpolationprotocol)  
[StringProtocol](https://developer.apple.com/documentation/swift/stringprotocol)  
[TextOutputStream](https://developer.apple.com/documentation/swift/textoutputstream)  
[TextOutputStreamable](https://developer.apple.com/documentation/swift/textoutputstreamable)  
[UnicodeCodec](https://developer.apple.com/documentation/swift/unicodecodec)  
[UnkeyedDecodingContainer](https://developer.apple.com/documentation/swift/unkeyeddecodingcontainer)  
[UnkeyedEncodingContainer](https://developer.apple.com/documentation/swift/unkeyedencodingcontainer)  
[UnsignedInteger](https://developer.apple.com/documentation/swift/unsignedinteger)  
[\_AppendKeyPath](https://developer.apple.com/documentation/swift/appendkeypath)

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [July 8, 2021, 8:00pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/9 "2021-07-08T20:00:11Z")

</div>

> [@Paul\_Cantrell](#):
>
> From the language user’s point of view, I’m hard-pressed to think of any logical reason why any protocol would _not_ want `Never` to conform to it.

The 2 reasons I know of why `Never` would not semantically conform to a protocol are:

- an infallible initializer or static var of `Self` type (would need to fatalError).
- The protocol is 'closed' (internally exhaustive) and the author did not consider `Never` conforming.

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [July 8, 2021, 8:43pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/10 "2021-07-08T20:43:12Z")

</div>

> [@Dante-Broggi](#):
>
> an infallible initializer or static var of `Self` type (would need to fatalError).

Ah, and thus `var p: P = Never(…)` should logically compile, which is…not nice.

And then there’s the problem of conflicting protocol requirements:

```
protocol P0 { var x: Int { get } }
protocol P1 { var x: String { get } }
// How can Never conform to both?

```

It seems to me it might be possible to get around both these problems by prohibiting access to all protocol requirements — initializers, static and instance members, everything — via the naked `Never` type:

```
func f(p0: P0, never: Never) {
  p0.x // allowed
  never.x // not allowed, even though Never conforms to P0
}

```

Hard to shake the feeling there’s a solution lurking around the corner here. However, I do now see how this becomes a rabbit hole, thanks to your comment!

> [@Dante-Broggi](#):
>
> The protocol is 'closed' (internally exhaustive) and the author did not consider `Never` conforming.

What would the pitfall of this be in practice? The `Never` type is unoccupied, so e.g. switching on the runtime type of a value can’t ever hit an unexpected non-match:

```
protocol P { }
struct A: P { }
struct B: P { }
extension Never: P {}

func f(_ p: P) {
    switch p {
        case is A: print("a")
        case is B: print("b")
        default: fatalError("unreachable") // This is in fact unreachable, even though Never: P
    }
}

```

Hmm, I suppose one could gum things up by switching on the metatype of a presumed-exhaustive protocol:

```
func f(_ p: P.Type) { … }
f(Never.self)

```

Is that the concern? Is there more I’m missing?

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [July 9, 2021, 12:08am UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/11 "2021-07-09T00:08:54Z")

</div>

> [@Paul\_Cantrell](#):
>
> Hmm, I suppose one could gum things up by switching on the metatype of a presumed-exhaustive protocol:
> 
> ```swift
> func f(_ p: P.Type) { … }
> f(Never.self)
> 
> ```
> 
> Is that the concern? Is there more I’m missing?

That's what I was thinking of in particular. I don't have any ideas of what one would switch on the metatype for, but it works, and making `Never` conform to such protocols would change the behavior.

---

<div class="post-metadata">

**Author:** ![jayton](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jayton/32/5592_2.png) [@jayton](https://forums.swift.org/u/jayton)\
**Post date:** [July 9, 2021, 10:56am UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/12 "2021-07-09T10:56:49Z")

</div>

> [@Paul\_Cantrell](#):
>
> It seems to me it might be possible to get around both these problems by prohibiting access to all protocol requirements — initializers, static and instance members, everything — via the naked `Never` type:

What about the disguised `Never` type? Recall that types can be materialized in any generic function:

```swift
protocol DefaultInitializable {
    init()
}

func instantiate<T: DefaultInitializable>() -> T {
    return T()
}

let n: Never = instantiate()

```

The same problem applies to all static methods and properties (not just Self-constrained or otherwise “fancy” ones).

One could work around this by `fatalError`ing, or maybe returning `nil` for nullable initializers, but this strikes me as unprincipled; depending on your point of view, it’s either turning an error that should be static into a dynamic one, or implicitly adding ad-hoc behaviour to the bottom type.

It would also require the static parts of protocol conformances to actually be synthesized for `Never` (either up front or through special runtime synthesis), whereas use of `Never` as a subtype of a concrete type should never incur overhead.

---

<div class="post-metadata">

**Author:** ![griotspeak](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/griotspeak/32/1966_2.png) [@griotspeak](https://forums.swift.org/u/griotspeak)\
**Post date:** [July 9, 2021, 7:25pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/13 "2021-07-09T19:25:53Z")

</div>

Runni

> [@ricketson](#):
>
> However, being a bottom type does _not_ imply that `Never` should implicitly conform to all protocols. Instead, convenient protocol conformances for `Never` should be added as deemed useful or necessary

Running the risk of derailing this proposal, which is not my intent. (+1 from me)

Why don’t we make adding scoped conformance trivial?

---

<div class="post-metadata">

**Author:** ![tomerd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tomerd/32/3402_2.png) [@tomerd](https://forums.swift.org/u/tomerd)\
**Post date:** [July 15, 2021, 3:57pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/14 "2021-07-15T15:57:26Z")

</div>

This review for SE-0319 has concluded and the proposal was [accepted](https://forums.swift.org/t/accepted-se-0319-never-as-identifiable/50473).

Thank you to everyone for the feedback and contributions to this proposal.

---

<div class="post-metadata">

**Author:** ![tomerd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tomerd/32/3402_2.png) [@tomerd](https://forums.swift.org/u/tomerd)\
**Post date:** [July 15, 2021, 3:57pm UTC](https://forums.swift.org/t/se-0319-never-as-identifiable/50246/15 "2021-07-15T15:57:30Z")

</div>

Closed on July 15, 2021, 3:57pm UTC


