<p>A never type represents an expression that is never evaluated or the type of an expression that represents an unreachable point in a program. The return value of an <code>exit()</code> or <code>abort()</code> function could be of such a type. C partially implements this for functions only as <code>_Noreturn</code> but this is only a specifier and not a distinct type.</p>
<p>A more useful implementation would include semantics such as:</p>
<ul>
<li>Being a type: <code>never_type abort(void);</code> instead of a specifier <code>_Noreturn void abort()</code>.</li>
<li>Being implicitly convertible to any type: <code>int x = abort();</code>. The function never returns, so matching the nonexistent return <em>'value'</em> to the expected type of the expression is irrelevant.</li>
<li><code>unreachable()</code> or <code>__builtin_unreachable()</code> would have this type. These are used to designate points of the program that will never be reached during execution by the program control flow. In C these are just <code>void</code> typed and invoke undefined behavior if reached.</li>
</ul>
<p>Rust has a <em>'never'</em> type but many languages do not. Are there any disadvantages to including this type?</p>

<types><never-type>
Are there disadvantages of including a never type?
CC BY-SA 4.0
2023-07-07T23:00:07.467Z
Is this concept coherent in dynamically typed languages, or only in statically typed ones?
Karl Knechtel
<p>If your language supports sum types, then it would be a bit duplicative to include another <code>never</code> type, unless it's a definition in the standard library. Because any empty sum type (like <code>enum Never {}</code> in Rust) <em>is</em> a never type.</p>

CC BY-SA 4.0
2023-05-16T20:53:26.823Z
2023-05-16T20:53:26.823Z
ice1000
<p><code>never</code> in Typescript can sometimes cause error messages to be more difficult to understand. For example:</p>
<pre class="lang-typescript prettyprint-override"><code>type Foo = {a: number, b: string}

function copyField(foo1: Foo, foo2: Foo, key: 'a' | 'b'): void {
    foo2[key] = foo1[key];
}
</code></pre>
<p>The assignment fails with the error:</p>
<blockquote>
<p>Type 'string | number' is not assignable to type 'never'.</p>
</blockquote>
<p>A more useful error message might be something like:</p>
<blockquote>
<p>Type 'string | number' cannot be assigned to a property of narrower type 'string &amp; number'.</p>
</blockquote>
<p>The error is that the property being assigned could either be a string or a number, so the value must be <em>both</em> in order to be assignable to either property. Because Typescript has a <code>never</code> type, the intersection <code>string &amp; number</code> gets reduced to <code>never</code> before the error has a chance to be reported. In principle it would be possible to keep <code>never</code> while also improving error messages in cases like this, but it adds complexity to the compiler backend.</p>
<hr />
<p>Another issue with <code>never</code> in Typescript is that a statement which produces a value of type <code>never</code> cannot (soundly) complete normally, so e.g. <code>fail(); console.log(&quot;unreachable&quot;);</code>  will never log. But this means the control-flow graph of a program depends on the types, when the types <em>also</em> depend on control-flow (when type guards or other narrowing conditions are checked).</p>
<p>This means in practice that type-checking and control-flow resolution must be done together in the same pass, because each depends on information from the other ─ again adding complexity to the compiler backend.</p>

CC BY-SA 4.0
2023-05-16T20:51:01.270Z
2023-07-05T02:17:07.337Z
2023-07-05T02:17:07.337Z
kaya3
<p><strong>Bottom Types</strong></p>
<p>I see no disadvantage in having a programming language match the mathematical theory.</p>
<p>What you and the answers describe as a <em>Never type</em>, is for me extremely close to the <a href="https://en.wikipedia.org/wiki/Bottom_type" rel="nofollow noreferrer"><em>Bottom type</em></a>, otherwise known as symbol ⊥ , or   _ | _</p>
<p>It can symbolize abort or exit like the OP says, but for me more importantly it symbolises the indecidable/incompleteness, or impossibility to know if the computation will halt or not.</p>
<p>I think only programming languages that are scope-limited enough to guarantee that they will finish would benefit from not having a Bottom type.</p>
<p>Small calculators are probably guaranteed to finish their computations. But my culture is too limited to know many more other computing process that are sure to finish without infinite loop or crash-bug due to .... many things.</p>
<p>(Any correcting comment is welcome)</p>

CC BY-SA 4.0
2023-05-30T15:33:12.387Z
2023-05-30T16:15:46.993Z
2023-05-30T16:15:46.993Z
Stephane Rolland
CC BY-SA 4.0
2023-07-07T22:57:41.457Z
This seems to discuss the general topic, but not really attempt an answer.
Karl Knechtel
<h1>Nulls</h1>
<p>If a language allows <code>null</code> to be a canonical instance of all types, then <code>never</code> is actually inhabited by <code>null</code>. You may say we can avoid this by adding a special rule, but consider the following example (with generics):</p>
<pre><code>func addNull&lt;T&gt;(List&lt;T&gt; list) {
  list.add(null);
}

addNull&lt;never&gt;(new List&lt;&gt;());
</code></pre>
<p>In this case it's very hard to forbid <code>null</code> as an instance of <code>never</code>.</p>

CC BY-SA 4.0
2023-05-16T20:56:35.470Z
2023-05-16T20:56:35.470Z
ice1000
CC BY-SA 4.0
2023-05-18T22:10:28.100Z
Your answer makes it look like it's a downside of having a “never” type, but it's really not. [Automatic null in types are a bad idea regardless](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/).
Gilles 'SO- stop being evil'
CC BY-SA 4.0
2023-05-16T21:03:11.643Z
Well, if `never` is inhabited by `null` in a C-style language, then `null` would would just mean `unreachable()` and reaching it would be undefined behavior.
CPlus
CC BY-SA 4.0
2023-05-16T21:53:03.963Z
@user16217248 This precludes null-checking.
wizzwizz4
<p><a href="https://mercurylang.org/" rel="nofollow noreferrer">Mercury</a>, being a logic language, has non-returning behaviour as part of the <em>determinism</em> system rather than the <em>type</em> system.</p>
<p>As well as &quot;this has one solution&quot; (deterministic or semideterministic) and &quot;this may have multiple solutions&quot; (multideterministic or nondeterministic), Mercury has two annotations which means &quot;this has no solutions&quot;:</p>
<ul>
<li><code>failure</code> means that it has no solutions and it can fail. The goal <code>fail</code> has this determinism.</li>
<li><code>erroneous</code> means that it has no solutions but it cannot fail. Goals that abort or raise an exception are examples.</li>
</ul>
<p>The reason why this works is so that Mercury has strong modes (i.e. strong dataflow) as well. Code like this is just fine:</p>
<pre><code>% semidet means that it will produce at most one solution,
% but can fail.
:- mode some_condition(in, out) is semidet.

% det means deterministic
:- mode generate_a_variable(in, out) is det.

% This never returns.
:- mode error(in) is erroneous.

:- mode p(in, out) is det.
p(X, Z) :-
    (if
        % The semantics of if-then-else is that
        % the &quot;then&quot; case is taken if the condition
        % succeeds, and the &quot;else&quot; case is taken if
        % it fails.
        some_condition(X, Y)
    then
        % Note that the variable Z here is returned from
        % the predicate.
        generate_a_variable(Y, Z)
    else
        % It doesn't matter that the variable Z is not
        % &quot;produced&quot; by the else case, because the compiler
        % knows this does not return.
        error(&quot;this case cannot occur&quot;)
    ).
</code></pre>

CC BY-SA 4.0
2023-06-13T04:07:01.120Z
2023-06-13T04:07:01.120Z
Pseudonym
<h1>Pointers</h1>
<p>If you can cast a <code>void*</code> to a <code>never*</code> and dereference it, you have an expression of type <code>never</code> that doesn't actually end control flow! Consider this Swift code:</p>
<pre class="lang-swift prettyprint-override"><code>import Foundation

func unsafeAllocZeroed&lt;T&gt;(_: T.Type = T.self) -&gt; UnsafeMutablePointer&lt;T&gt;? {
  calloc(1, MemoryLayout&lt;T&gt;.stride)?.bindMemory(to: T.self, capacity: 1)
}

if let ptr = unsafeAllocZeroed(Never.self) {
  print(&quot;ptr alloc'd, dereferencing&quot;)
  ptr.pointee // expression of type Never; logically, program flow may not pass here
  print(&quot;How did we get here?&quot;)
} else {
  print(&quot;that makes sense&quot;)
}
</code></pre>
<p>In my testing, this <em>always</em> prints &quot;How did we get here?&quot;. <a href="https://swiftfiddle.com/3ls3qetrbvbpzkbednamznma2u" rel="nofollow noreferrer">SwiftFiddle link</a> if you want to try it yourself.</p>
<p>For even more fun, you can <code>throw</code> the Never, and get a segfault.</p>

CC BY-SA 4.0
2023-05-30T13:06:25.617Z
2023-05-30T13:06:25.617Z
Bbrk24
CC BY-SA 4.0
2023-05-30T14:22:31.673Z
This seems to be a problem with allowing this cast ─ and I don't see why the cast should be allowed.
kaya3
CC BY-SA 4.0
2023-05-30T17:18:57.897Z
@kaya3 This is actually UB, but not for the reason you might think: `ptr.pointee` is referencing uninitialized memory. I also posted about this on the Swift forums, if you want to look: https://forums.swift.org/t/pointers-to-never/65257
Bbrk24
CC BY-SA 4.0
2023-11-08T12:52:56.040Z
Hmm. Unsafe code being unsafe, isn't really a disadvantage of Never.
Eldritch Conundrum
CC BY-SA 4.0
2023-11-08T22:40:04.290Z
@EldritchConundrum In current Swift, it is possible to do this without ever typing the word `Unsafe`. I did it here for clarity. (Arguably that's a Swift issue and not a `Never` issue, but pointers being weird should still be considered.)
Bbrk24
<h1>It doesn’t play nice with cross-language interop</h1>
<p>The C++ standard library includes a type that is exactly 1 byte, but not implicitly convertible to or from any integer or character type. It’s defined as follows:</p>
<pre class="lang-cpp prettyprint-override"><code>namespace std {
enum class byte : unsigned char {};
}
</code></pre>
<p>If your language models sum types as enums, like in Swift or Rust, don’t assume other languages do the same. Swift made this exact mistake, so it’s perfectly legal to write</p>
<pre class="lang-swift prettyprint-override"><code>import CxxStdlib

func magic&lt;T&gt;(_ x: std.byte) -&gt; T {
  switch x {}
}
</code></pre>
<p>and violate the memory safety rules Swift tries to maintain.</p>

CC BY-SA 4.0
2023-06-12T17:33:17.787Z
2023-06-13T04:15:05.840Z
2023-06-13T04:15:05.840Z
Bbrk24
<p>The C standard specifies that infinite loops with no side-effects are undefined behaviour<sup>1</sup>, and LLVM follows this, so the LLVM optimiser sometimes &quot;optimises away&quot; such infinite loops (by deleting them).</p>
<p>If the type of an infinite loop is inferred as <code>never</code>, then the LLVM optimiser removes the infinite loop, then you may have accidentally &quot;produced a value&quot; of type <code>never</code>, leading to unsoundness. This problem occurred in early versions of Rust, for example: see <a href="https://github.com/rust-lang/rust/issues/28728" rel="noreferrer">this issue</a>.</p>
<p>This bug might recur if your language uses LLVM and has a <code>never</code> type, so be careful!</p>
<hr />
<p><sup>1</sup> The reason for this is so that the compiler can delete a loop, if nothing that loop computes is ever used afterwards: now the compiler doesn't need to check that the loop terminates (which is undecidable in general) before applying this optimisation.</p>

CC BY-SA 4.0
2023-05-16T21:23:24.110Z
2023-05-16T21:51:33.280Z
2023-05-16T21:51:33.280Z
pxeger
CC BY-SA 4.0
2023-07-05T15:43:07.187Z
One of the weird things you can do with this "optimization" is [to "disprove" Fermat's Last Theroem](https://blog.regehr.org/archives/140), as long as you don't try to print the counterexample.
dan04
CC BY-SA 4.0
2023-05-16T21:30:36.850Z
`while(1);` seems to be equivalent to `*(int *)NULL = 0;` or `__builtin_unreachable();`
CPlus
CC BY-SA 4.0
2023-11-08T20:41:32.683Z
@dan04: A much more interesting thing one can do is cause a compiler to transform something like `while(x != (uint16_t)i) i*=3; if (x < 65536) array[x] = 1;` into an unconditional `array[x] = 1;` that will get executed even if `x` exceeds 65536.  I doubt the Standard was ever intended to be seen as inviting such dangerous nonsense, but the authors of clang and gcc seem to think it was.
supercat
CC BY-SA 4.0
2023-11-08T20:45:04.743Z
@dan04: I disagree with that blog authors' claim that compilers should be forbidden from reordering loops across following code which has no data dependencies unless they can prove the loops terminate.  What should be forbidden, however, is for compilers to generate downstream code which relies upon a loop's termination condition having been satisfied, without regarding that as a data dependency upon a computation within the loop.
supercat
<h1>Transitively uninhabitable types</h1>
<p>Swift considers all these types to behave as <code>Never</code> does:</p>
<ul>
<li>an enum with no cases, e.g. <code>enum Never {}</code> itself</li>
<li>a struct or tuple with an uninhabitable field, e.g. <code>struct Foo { var bar: Never }</code></li>
<li>an enum whose cases are all uninhabitable, e.g. <code>enum E { case a(Never), b(Foo) }</code></li>
</ul>
<p>This adds significant complexity to the type checker. Without being able to see type definitions, you can’t know whether <code>My&lt;Deeply&lt;Nested&lt;Struct&lt;Type&gt;&gt;&gt;&gt;</code> is equivalent to <code>Never</code>.</p>

CC BY-SA 4.0
2023-05-16T19:44:59.577Z
2023-05-16T19:44:59.577Z
Bbrk24
CC BY-SA 4.0
2023-07-23T19:57:35.757Z
These rules may look complex, but if you replace struct by product, enum by sum, and Never by zero, you get "Zero can be either: the sum of zero naturals, any product that includes a zero, or a sum of numbers that are all zeros."
Eldritch Conundrum
CC BY-SA 4.0
2023-05-16T19:50:59.283Z
It would be considered *'incomplete'* in a C-style language. You could not have a `never` typed member in a `struct`.
CPlus
CC BY-SA 4.0
2023-05-16T19:51:44.497Z
Swift lets you write it. There’s not much reason to explicitly do so, but sometimes it happens with generic types.
Bbrk24
# Are there disadvantages of including a never type?
Posted by: username_0 on 2023-05-16
A never type represents an expression that is never evaluated or the type of an expression that represents an unreachable point in a program. The return value of an `exit()` or `abort()` function could be of such a type. C partially implements this for functions only as `_Noreturn` but this is only a specifier and not a distinct type.

A more useful implementation would include semantics such as:

* Being a type: `never_type abort(void);` instead of a specifier `_Noreturn void abort()`.
* Being implicitly convertible to any type: `int x = abort();`. The function never returns, so matching the nonexistent return *'value'* to the expected type of the expression is irrelevant.
* `unreachable()` or `__builtin_unreachable()` would have this type. These are used to designate points of the program that will never be reached during execution by the program control flow. In C these are just `void` typed and invoke undefined behavior if reached.

Rust has a *'never'* type but many languages do not. Are there any disadvantages to including this type?
**Tags:** types never-type
> **Comments:**
> **username_1**: Is this concept coherent in dynamically typed languages, or only in statically typed ones?  
---
## 9 answers
### Answer by username_10 on 2023-05-16. Score: 18 | Accepted answer
The C standard specifies that infinite loops with no side-effects are undefined behaviour1, and LLVM follows this, so the LLVM optimiser sometimes "optimises away" such infinite loops (by deleting them).

If the type of an infinite loop is inferred as `never`, then the LLVM optimiser removes the infinite loop, then you may have accidentally "produced a value" of type `never`, leading to unsoundness. This problem occurred in early versions of Rust, for example: see [this issue](https://github.com/rust-lang/rust/issues/28728).

This bug might recur if your language uses LLVM and has a `never` type, so be careful!

---

1 The reason for this is so that the compiler can delete a loop, if nothing that loop computes is ever used afterwards: now the compiler doesn't need to check that the loop terminates (which is undecidable in general) before applying this optimisation.
> **Comments:**
> **username_0** (2023-05-16): `while(1);` seems to be equivalent to `*(int *)NULL = 0;` or `__builtin_unreachable();`  
> **username_11** (2023-07-05): One of the weird things you can do with this "optimization" is [to "disprove" Fermat's Last Theroem](https://blog.regehr.org/archives/140), as long as you don't try to print the counterexample.  
> **username_12** (2023-11-08): @dan04: A much more interesting thing one can do is cause a compiler to transform something like `while(x != (uint16_t)i) i*=3; if (x < 65536) array[x] = 1;` into an unconditional `array[x] = 1;` that will get executed even if `x` exceeds 65536.  I doubt the Standard was ever intended to be seen as inviting such dangerous nonsense, but the authors of clang and gcc seem to think it was.  
> **username_12** (2023-11-08): @dan04: I disagree with that blog authors' claim that compilers should be forbidden from reordering loops across following code which has no data dependencies unless they can prove the loops terminate.  What should be forbidden, however, is for compilers to generate downstream code which relies upon a loop's termination condition having been satisfied, without regarding that as a data dependency upon a computation within the loop.  
---
### Answer by username_8 on 2023-05-16. Score: 9
# Transitively uninhabitable types

Swift considers all these types to behave as `Never` does:

* an enum with no cases, e.g. `enum Never {}` itself
* a struct or tuple with an uninhabitable field, e.g. `struct Foo { var bar: Never }`
* an enum whose cases are all uninhabitable, e.g. `enum E { case a(Never), b(Foo) }`

This adds significant complexity to the type checker. Without being able to see type definitions, you can’t know whether `My>>>` is equivalent to `Never`.
> **Comments:**
> **username_0** (2023-05-16): It would be considered *'incomplete'* in a C-style language. You could not have a `never` typed member in a `struct`.  
> **username_8** (2023-05-16): Swift lets you write it. There’s not much reason to explicitly do so, but sometimes it happens with generic types.  
> **username_9** (2023-07-23): These rules may look complex, but if you replace struct by product, enum by sum, and Never by zero, you get "Zero can be either: the sum of zero naturals, any product that includes a zero, or a sum of numbers that are all zeros."  
---
### Answer by username_2 on 2023-05-16. Score: 7
If your language supports sum types, then it would be a bit duplicative to include another `never` type, unless it's a definition in the standard library. Because any empty sum type (like `enum Never {}` in Rust) *is* a never type.
---
### Answer by username_3 on 2023-05-16. Score: 6
never in Typescript can sometimes cause error messages to be more difficult to understand. For example:
type Foo = {a: number, b: string}

function copyField(foo1: Foo, foo2: Foo, key: 'a' | 'b'): void {
    foo2[key] = foo1[key];
}

The assignment fails with the error:

Type 'string | number' is not assignable to type 'never'.

A more useful error message might be something like:

Type 'string | number' cannot be assigned to a property of narrower type 'string & number'.

The error is that the property being assigned could either be a string or a number, so the value must be both in order to be assignable to either property. Because Typescript has a never type, the intersection string & number gets reduced to never before the error has a chance to be reported. In principle it would be possible to keep never while also improving error messages in cases like this, but it adds complexity to the compiler backend.

Another issue with never in Typescript is that a statement which produces a value of type never cannot (soundly) complete normally, so e.g. fail(); console.log("unreachable");  will never log. But this means the control-flow graph of a program depends on the types, when the types also depend on control-flow (when type guards or other narrowing conditions are checked).
This means in practice that type-checking and control-flow resolution must be done together in the same pass, because each depends on information from the other ─ again adding complexity to the compiler backend.
---
### Answer by username_4 on 2023-05-30. Score: 4
**Bottom Types**

I see no disadvantage in having a programming language match the mathematical theory.

What you and the answers describe as a *Never type*, is for me extremely close to the [*Bottom type*](https://en.wikipedia.org/wiki/Bottom_type), otherwise known as symbol ⊥ , or \_ | \_

It can symbolize abort or exit like the OP says, but for me more importantly it symbolises the indecidable/incompleteness, or impossibility to know if the computation will halt or not.

I think only programming languages that are scope-limited enough to guarantee that they will finish would benefit from not having a Bottom type.

Small calculators are probably guaranteed to finish their computations. But my culture is too limited to know many more other computing process that are sure to finish without infinite loop or crash-bug due to .... many things.

(Any correcting comment is welcome)
> **Comments:**
> **username_1** (2023-07-07): This seems to discuss the general topic, but not really attempt an answer.  
---
### Answer by username_2 on 2023-05-16. Score: 4
Nulls
If a language allows null to be a canonical instance of all types, then never is actually inhabited by null. You may say we can avoid this by adding a special rule, but consider the following example (with generics):
func addNull(List list) {
  list.add(null);
}

addNull(new List<>());

In this case it's very hard to forbid null as an instance of never.
> **Comments:**
> **username_0** (2023-05-16): Well, if `never` is inhabited by `null` in a C-style language, then `null` would would just mean `unreachable()` and reaching it would be undefined behavior.  
> **username_6** (2023-05-16): @user16217248 This precludes null-checking.  
> **username_5** (2023-05-18): Your answer makes it look like it's a downside of having a “never” type, but it's really not. [Automatic null in types are a bad idea regardless](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/).  
---
### Answer by username_7 on 2023-06-13. Score: 2
Mercury, being a logic language, has non-returning behaviour as part of the determinism system rather than the type system.
As well as "this has one solution" (deterministic or semideterministic) and "this may have multiple solutions" (multideterministic or nondeterministic), Mercury has two annotations which means "this has no solutions":

failure means that it has no solutions and it can fail. The goal fail has this determinism.
erroneous means that it has no solutions but it cannot fail. Goals that abort or raise an exception are examples.

The reason why this works is so that Mercury has strong modes (i.e. strong dataflow) as well. Code like this is just fine:
% semidet means that it will produce at most one solution,
% but can fail.
:- mode some_condition(in, out) is semidet.

% det means deterministic
:- mode generate_a_variable(in, out) is det.

% This never returns.
:- mode error(in) is erroneous.

:- mode p(in, out) is det.
p(X, Z) :-
    (if
        % The semantics of if-then-else is that
        % the "then" case is taken if the condition
        % succeeds, and the "else" case is taken if
        % it fails.
        some_condition(X, Y)
    then
        % Note that the variable Z here is returned from
        % the predicate.
        generate_a_variable(Y, Z)
    else
        % It doesn't matter that the variable Z is not
        % "produced" by the else case, because the compiler
        % knows this does not return.
        error("this case cannot occur")
    ).
---
### Answer by username_8 on 2023-05-30. Score: 1
Pointers
If you can cast a void* to a never* and dereference it, you have an expression of type never that doesn't actually end control flow! Consider this Swift code:
import Foundation

func unsafeAllocZeroed(_: T.Type = T.self) -> UnsafeMutablePointer? {
  calloc(1, MemoryLayout.stride)?.bindMemory(to: T.self, capacity: 1)
}

if let ptr = unsafeAllocZeroed(Never.self) {
  print("ptr alloc'd, dereferencing")
  ptr.pointee // expression of type Never; logically, program flow may not pass here
  print("How did we get here?")
} else {
  print("that makes sense")
}

In my testing, this always prints "How did we get here?". SwiftFiddle link if you want to try it yourself.
For even more fun, you can throw the Never, and get a segfault.
> **Comments:**
> **username_3** (2023-05-30): This seems to be a problem with allowing this cast ─ and I don't see why the cast should be allowed.  
> **username_8** (2023-05-30): @kaya3 This is actually UB, but not for the reason you might think: `ptr.pointee` is referencing uninitialized memory. I also posted about this on the Swift forums, if you want to look: https://forums.swift.org/t/pointers-to-never/65257  
> **username_9** (2023-11-08): Hmm. Unsafe code being unsafe, isn't really a disadvantage of Never.  
> **username_8** (2023-11-08): @EldritchConundrum In current Swift, it is possible to do this without ever typing the word `Unsafe`. I did it here for clarity. (Arguably that's a Swift issue and not a `Never` issue, but pointers being weird should still be considered.)  
---
### Answer by username_8 on 2023-06-12. Score: 1
It doesn’t play nice with cross-language interop
The C++ standard library includes a type that is exactly 1 byte, but not implicitly convertible to or from any integer or character type. It’s defined as follows:
namespace std {
enum class byte : unsigned char {};
}

If your language models sum types as enums, like in Swift or Rust, don’t assume other languages do the same. Swift made this exact mistake, so it’s perfectly legal to write
import CxxStdlib

func magic(_ x: std.byte) -> T {
  switch x {}
}

and violate the memory safety rules Swift tries to maintain.
---
