Skip to content

Commit 75b8ec9

Browse files
Merge pull request #206 from canndrew/never_type
add docs for never type
2 parents a8755cc + 8671941 commit 75b8ec9

File tree

5 files changed

+18
-55
lines changed

5 files changed

+18
-55
lines changed

src/expressions/loop-expr.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ Only `loop` supports [evaluation to non-trivial values](#break-and-loop-values).
3636
A `loop` expression repeats execution of its body continuously:
3737
`loop { println!("I live."); }`.
3838

39-
A `loop` expression without an associated `break` expression is
40-
[diverging](items/functions.html#diverging-functions), and doesn't
41-
return anything. A `loop` expression containing associated
42-
[`break` expression(s)](#break-expressions)
43-
may terminate, and must have type compatible with the value of the `break`
44-
expression(s).
39+
A `loop` expression without an associated `break` expression is diverging and
40+
has type [`!`](types.html#never-type). A `loop` expression containing
41+
associated [`break` expression(s)](#break-expressions) may terminate, and must
42+
have type compatible with the value of the `break` expression(s).
4543

4644
## Predicate loops
4745

src/items/functions.md

+1-47
Original file line numberDiff line numberDiff line change
@@ -93,52 +93,6 @@ sufficient context to determine the type parameters. For example,
9393

9494
[path]: paths.html
9595

96-
## Diverging functions
97-
98-
A special kind of function can be declared with a `!` character where the
99-
output type would normally be. For example:
100-
101-
```rust
102-
fn my_err(s: &str) -> ! {
103-
println!("{}", s);
104-
panic!();
105-
}
106-
```
107-
108-
We call such functions "diverging" because they never return a value to the
109-
caller. Every control path in a diverging function must end with a `panic!()`,
110-
a loop expression without an associated break expression, or a call to another
111-
diverging function on every control path. The `!` annotation does *not* denote
112-
a type.
113-
114-
It might be necessary to declare a diverging function because as mentioned
115-
previously, the typechecker checks that every control path in a function ends
116-
with a [`return`] or diverging expression. So, if `my_err` were declared
117-
without the `!` annotation, the following code would not typecheck:
118-
119-
[`return`]: expressions/return-expr.html
120-
121-
```rust
122-
# fn my_err(s: &str) -> ! { panic!() }
123-
124-
fn f(i: i32) -> i32 {
125-
if i == 42 {
126-
return 42;
127-
}
128-
else {
129-
my_err("Bad number!");
130-
}
131-
}
132-
```
133-
134-
This will not compile without the `!` annotation on `my_err`, since the `else`
135-
branch of the conditional in `f` does not return an `i32`, as required by the
136-
signature of `f`. Adding the `!` annotation to `my_err` informs the typechecker
137-
that, should control ever enter `my_err`, no further type judgments about `f`
138-
need to hold, since control will never resume in any context that relies on
139-
those judgments. Thus the return type on `f` only needs to reflect the `if`
140-
branch of the conditional.
141-
14296
## Extern functions
14397

14498
Extern functions are part of Rust's foreign function interface, providing the
@@ -169,4 +123,4 @@ As non-Rust calling conventions do not support unwinding, unwinding past the end
169123
of an extern function will cause the process to abort. In LLVM, this is
170124
implemented by executing an illegal instruction.
171125

172-
[external blocks]: items/external-blocks.html
126+
[external blocks]: items/external-blocks.html

src/special-types-and-traits.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ whose type implements `Copy` are copied rather than moved upon assignment.
5252
fields that are not `Copy`. `Copy` is implemented by the compiler for
5353

5454
* [Numeric types]
55-
* `char` and `bool`
55+
* `char`, `bool` and [`!`]
5656
* [Tuples] of `Copy` types
5757
* [Arrays] of `Copy` types
5858
* [Shared references]
@@ -151,3 +151,4 @@ compiler, not by [implementation items].
151151
[Tuples]: types.html#tuple-types
152152
[Type parameters]: types.html#type-parameters
153153
[variance]: ../nomicon/subtyping.html
154+
[`!`]: types.html#never-type

src/type-coercions.md

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ Coercion is allowed between the following types:
148148

149149
* Non capturing closures to `fn` pointers
150150

151+
* `!` to any `T`
152+
151153
### Unsized Coercions
152154

153155
The following coercions are called `unsized coercions`, since they

src/types.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ types:
1717
* The [machine types] (integer and floating-point).
1818
* The [machine-dependent integer types].
1919
* The [textual types] `char` and `str`.
20+
* The [never type] `!`
2021

2122
There are also some primitive constructs for generic types built in to the
2223
language:
@@ -31,6 +32,7 @@ language:
3132
[machine types]: #machine-types
3233
[machine-dependent integer types]: #machine-dependent-integer-types
3334
[textual types]: #textual-types
35+
[never-type]: #never-type
3436
[Tuples]: #tuple-types
3537
[Arrays]: #array-and-slice-types
3638
[Slices]: #array-and-slice-types
@@ -84,6 +86,12 @@ unsigned bytes holding a sequence of UTF-8 code points. Since `str` is a
8486
[dynamically sized type], it is not a _first-class_ type, but can only be
8587
instantiated through a pointer type, such as `&str`.
8688

89+
## Never type
90+
91+
The never type `!` is a type with no values, representing the result of
92+
computations that never complete. Expressions of type `!` can be coerced into
93+
any other type.
94+
8795
## Tuple types
8896

8997
A tuple *type* is a heterogeneous product of other types, called the *elements*
@@ -653,4 +661,4 @@ impl Printable for String {
653661
[issue 47010]: https://github.com/rust-lang/rust/issues/47010
654662
[issue 33140]: https://github.com/rust-lang/rust/issues/33140
655663
[_PATH_]: paths.html
656-
[_LIFETIME_OR_LABEL_]: tokens.html#lifetimes-and-loop-labels
664+
[_LIFETIME_OR_LABEL_]: tokens.html#lifetimes-and-loop-labels

0 commit comments

Comments
 (0)