Skip to content

Commit

Permalink
Merge pull request #206 from canndrew/never_type
Browse files Browse the repository at this point in the history
add docs for never type
  • Loading branch information
matthewjasper authored Mar 16, 2018
2 parents a8755cc + 8671941 commit 75b8ec9
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 55 deletions.
10 changes: 4 additions & 6 deletions src/expressions/loop-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ Only `loop` supports [evaluation to non-trivial values](#break-and-loop-values).
A `loop` expression repeats execution of its body continuously:
`loop { println!("I live."); }`.

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

## Predicate loops

Expand Down
48 changes: 1 addition & 47 deletions src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,52 +93,6 @@ sufficient context to determine the type parameters. For example,

[path]: paths.html

## Diverging functions

A special kind of function can be declared with a `!` character where the
output type would normally be. For example:

```rust
fn my_err(s: &str) -> ! {
println!("{}", s);
panic!();
}
```

We call such functions "diverging" because they never return a value to the
caller. Every control path in a diverging function must end with a `panic!()`,
a loop expression without an associated break expression, or a call to another
diverging function on every control path. The `!` annotation does *not* denote
a type.

It might be necessary to declare a diverging function because as mentioned
previously, the typechecker checks that every control path in a function ends
with a [`return`] or diverging expression. So, if `my_err` were declared
without the `!` annotation, the following code would not typecheck:

[`return`]: expressions/return-expr.html

```rust
# fn my_err(s: &str) -> ! { panic!() }

fn f(i: i32) -> i32 {
if i == 42 {
return 42;
}
else {
my_err("Bad number!");
}
}
```

This will not compile without the `!` annotation on `my_err`, since the `else`
branch of the conditional in `f` does not return an `i32`, as required by the
signature of `f`. Adding the `!` annotation to `my_err` informs the typechecker
that, should control ever enter `my_err`, no further type judgments about `f`
need to hold, since control will never resume in any context that relies on
those judgments. Thus the return type on `f` only needs to reflect the `if`
branch of the conditional.

## Extern functions

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

[external blocks]: items/external-blocks.html
[external blocks]: items/external-blocks.html
3 changes: 2 additions & 1 deletion src/special-types-and-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ whose type implements `Copy` are copied rather than moved upon assignment.
fields that are not `Copy`. `Copy` is implemented by the compiler for

* [Numeric types]
* `char` and `bool`
* `char`, `bool` and [`!`]
* [Tuples] of `Copy` types
* [Arrays] of `Copy` types
* [Shared references]
Expand Down Expand Up @@ -151,3 +151,4 @@ compiler, not by [implementation items].
[Tuples]: types.html#tuple-types
[Type parameters]: types.html#type-parameters
[variance]: ../nomicon/subtyping.html
[`!`]: types.html#never-type
2 changes: 2 additions & 0 deletions src/type-coercions.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ Coercion is allowed between the following types:

* Non capturing closures to `fn` pointers

* `!` to any `T`

### Unsized Coercions

The following coercions are called `unsized coercions`, since they
Expand Down
10 changes: 9 additions & 1 deletion src/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ types:
* The [machine types] (integer and floating-point).
* The [machine-dependent integer types].
* The [textual types] `char` and `str`.
* The [never type] `!`

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

## Never type

The never type `!` is a type with no values, representing the result of
computations that never complete. Expressions of type `!` can be coerced into
any other type.

## Tuple types

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

0 comments on commit 75b8ec9

Please sign in to comment.