In everyday code you don't need to worry about it.
If you're just trying to figure out how to code Rust on a daily basis, the book may be a better resource than the reference.
I wrote these parts before your last comment. Usually things just work and you don't need to know these details. If it's confusing or too much right now, don't worry about understanding it, you don't need to understand anything extra to code on a daily basis.
Anyway --
The expression returns before the statement "completes".
if a > b // vvvvv This block has type () -- does not end with ;
{ // -----------------------------------------------------+
return a // This expression returns; it has type ! |
; // This statement has type () |
} // ------------------------------------------------------+
// ...
!
is the "never type" that @Embers-of-the-Fire mentioned.
Now you may ask, why does this work:
if a > b // vvvvv This block has type () (does not end with ;)
{ // -----------------------------------------------------+
return a // This expression returns; it has type ! |
} // ------------------------------------------------------+
And the reason is that !
is special: It can coerce to any other type, including ()
.
In fact it's a bit stronger than that: the compiler understands that control flow can't proceed past a !
, and thus the entire containing block can be coerced... but this is only permitted when there is no tail expression.
// this if/else has type f64
let _ = if a > b // -----------------------------------------------+
{ // ------------------------------------------------+ block |
return a // expression returns; has type ! | coerces |
; // statement has type () | to type |
71 // unreachable expression with type i32 | f64 |
; // statement has type () | thanks |
} // -------------------------------------------------+ to the ! |
else // |
{ // --------+ this block has type f64 |
0.0 // | (both branches must have the same type) |
} // --------+ |
// ---------------------------------------------------------------+
; // statement has type ()
(Playground.)
If you add a tail expression -- even ()
-- it doesn't compile.
I'm not sure if the reference covers this.