Skip to content

Commit 65eab6e

Browse files
committed
Add diverging functions to the book.
We use them in some places, but never actually talk about the syntax.
1 parent cf636c2 commit 65eab6e

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

src/doc/trpl/functions.md

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
You've already seen one function so far, the `main` function:
44

5-
```{rust}
5+
```rust
66
fn main() {
77
}
88
```
@@ -12,22 +12,22 @@ This is the simplest possible function declaration. As we mentioned before,
1212
this function takes no arguments, and then some curly braces to indicate the
1313
body. Here's a function named `foo`:
1414

15-
```{rust}
15+
```rust
1616
fn foo() {
1717
}
1818
```
1919

2020
So, what about taking arguments? Here's a function that prints a number:
2121

22-
```{rust}
22+
```rust
2323
fn print_number(x: i32) {
2424
println!("x is: {}", x);
2525
}
2626
```
2727

2828
Here's a complete program that uses `print_number`:
2929

30-
```{rust}
30+
```rust
3131
fn main() {
3232
print_number(5);
3333
}
@@ -42,7 +42,7 @@ you add a type to the argument name, after a colon.
4242

4343
Here's a complete program that adds two numbers together and prints them:
4444

45-
```{rust}
45+
```rust
4646
fn main() {
4747
print_sum(5, 6);
4848
}
@@ -58,7 +58,7 @@ as when you declare it.
5858
Unlike `let`, you _must_ declare the types of function arguments. This does
5959
not work:
6060

61-
```{ignore}
61+
```{rust,ignore}
6262
fn print_sum(x, y) {
6363
println!("x is: {}", x + y);
6464
}
@@ -79,7 +79,7 @@ sweet spot between full inference and no inference.
7979

8080
What about returning a value? Here's a function that adds one to an integer:
8181

82-
```{rust}
82+
```rust
8383
fn add_one(x: i32) -> i32 {
8484
x + 1
8585
}
@@ -90,7 +90,7 @@ Rust functions return exactly one value, and you declare the type after an
9090

9191
You'll note the lack of a semicolon here. If we added it in:
9292

93-
```{ignore}
93+
```{rust,ignore}
9494
fn add_one(x: i32) -> i32 {
9595
x + 1;
9696
}
@@ -123,7 +123,7 @@ semicolon in a return position would cause a bug.
123123

124124
But what about early returns? Rust does have a keyword for that, `return`:
125125

126-
```{rust}
126+
```rust
127127
fn foo(x: i32) -> i32 {
128128
if x < 5 { return x; }
129129

@@ -134,7 +134,7 @@ fn foo(x: i32) -> i32 {
134134
Using a `return` as the last line of a function works, but is considered poor
135135
style:
136136

137-
```{rust}
137+
```rust
138138
fn foo(x: i32) -> i32 {
139139
if x < 5 { return x; }
140140

@@ -160,5 +160,34 @@ fn foo(x: i32) -> i32 {
160160
Because `if` is an expression, and it's the only expression in this function,
161161
the value will be the result of the `if`.
162162

163-
There are some additional ways to define functions, but they involve features
164-
that we haven't learned about yet, so let's just leave it at that for now.
163+
## Diverging functions
164+
165+
Rust has some special syntax for 'diverging functions', which are functions that
166+
do not return:
167+
168+
```
169+
fn diverges() -> ! {
170+
panic!("This function never returns!");
171+
}
172+
```
173+
174+
`panic!` is a macro, similar to `println!()` that we've already seen. Unlike
175+
`println!()`, `panic!()` causes the current thread of execution to crash with
176+
the given message.
177+
178+
Because this function will cause a crash, it will never return, and so it has
179+
the type '`!`', which is read "diverges." A diverging function can be used
180+
as any type:
181+
182+
```should_fail
183+
# fn diverges() -> ! {
184+
# panic!("This function never returns!");
185+
# }
186+
187+
let x: i32 = diverges();
188+
let x: String = diverges();
189+
```
190+
191+
We don't have a good use for diverging functions yet, because they're used in
192+
conjunction with other Rust features. But when you see `-> !` later, you'll
193+
know what it's called.

0 commit comments

Comments
 (0)