rewrite never type documentation#158370
Conversation
There was a problem hiding this comment.
Due to the slightly messy diff, I ended up splitting my review up into many small comments, so apologies for the large number of them. Most are copy-edits, with a couple small content changes here and there. Feel free to use them or not as you see fit.
| /// `!` is the canonical uninhabited type. `!` represents the type of diverging computations -- | ||
| /// computations which never resolve to any value. |
There was a problem hiding this comment.
| /// `!` is the canonical uninhabited type. `!` represents the type of diverging computations -- | |
| /// computations which never resolve to any value. | |
| /// `!` represents the type of diverging computations -- computations which never resolve to any | |
| /// value. It the canonical uninhabited type. |
| /// For example, the [`exit`] function is defined as returning `!`, to signify that it doesn't | ||
| /// return normally and exits the process instead. Thus, any code following a call to [`exit`] is | ||
| /// unreachable. ([`panic!`] works the same way.) |
There was a problem hiding this comment.
| /// For example, the [`exit`] function is defined as returning `!`, to signify that it doesn't | |
| /// return normally and exits the process instead. Thus, any code following a call to [`exit`] is | |
| /// unreachable. ([`panic!`] works the same way.) | |
| /// For example, the [`exit`] function is defined as returning `!`, to signify that it exits the | |
| /// process instead of returning normally. Thus, any code following a call to [`exit`] is | |
| /// unreachable. The [`panic!`] macro works the same way. |
There was a problem hiding this comment.
I think your suggestion is misleading here. returning ! doesn't signify that the function exits the process, only that it doesn't return. Now realizing, that my version kind-of struggles from the same issue...
How about the following?
For example, the
exitfunction is defined as returning!, to signify that it doesn't return normally (as it exits the process instead).
| /// Similarly, [`return`], [`break`], [`continue`], [`become`], and infinite [`loop`] expressions | ||
| /// all have type `!`, as the code following them is unreachable. |
There was a problem hiding this comment.
Should become be included here if it is still unstable?
| /// This is because `impl Trait` is not a specific type in and of itself, but instead a marker that | ||
| /// the return type of the function is hidden and the only thing that can be assumed by the caller | ||
| /// is that whatever the type is, it implements `Trait`. |
There was a problem hiding this comment.
| /// This is because `impl Trait` is not a specific type in and of itself, but instead a marker that | |
| /// the return type of the function is hidden and the only thing that can be assumed by the caller | |
| /// is that whatever the type is, it implements `Trait`. | |
| /// Here, never-to-any coercion fails because `impl Trait` is not itself a concrete type, but rather | |
| /// a way to tell the compiler that a function's return type is hidden, and the only thing which can | |
| /// be assumed about this type is that it implements `Trait`. |
There was a problem hiding this comment.
Never-to-any doesn't fail here; the failure is that the hidden type doesn't implement the correct trait.
I rewrote "a specific type in and of itself" though.
| /// In case of using `todo!()` the hidden return type is inferred to be `!`, which may not | ||
| /// implement the trait. |
There was a problem hiding this comment.
| /// In case of using `todo!()` the hidden return type is inferred to be `!`, which may not | |
| /// implement the trait. | |
| /// The compiler then attempts to choose such a concrete type, but is unable to do so. In this case, | |
| /// we abandon the coercion and fall back to just the never type itself, which will fail to compile | |
| /// if `!` does not implement `Trait`. |
I think fallback should be explicitly mentioned here.
There was a problem hiding this comment.
The compiler then attempts to choose such a concrete type, but is unable to do so.
This is not true; the compiler chooses ! here.
I think mentioning fallback here only makes it more confusing...
Co-authored-by: Kevin Reid <kpreid@switchb.org>
Co-authored-by: Kevin Reid <kpreid@switchb.org> Co-authored-by: Michael Krasnitski <42564254+mkrasnitski@users.noreply.github.com> Co-authored-by: waffle <waffle.lapkin@gmail.com>
Co-authored-by: Michael Krasnitski <42564254+mkrasnitski@users.noreply.github.com>
f2dc120 to
cd5b51c
Compare
| /// This is because `impl Trait` is not a specific type in and of itself, but instead a marker that | ||
| /// the return type of the function is hidden and the only thing that can be assumed by the caller | ||
| /// is that whatever the type is, it implements `Trait`. |
There was a problem hiding this comment.
Never-to-any doesn't fail here; the failure is that the hidden type doesn't implement the correct trait.
I rewrote "a specific type in and of itself" though.
| /// At first glance there is no reason to implement any traits for `!`. Most traits take a value | ||
| /// of `Self` as an argument in methods, so you won't be able to call them anyway. |
There was a problem hiding this comment.
Incorporated this into my last commit.
View all comments
With the never type stabilization approaching, I think the documentation could be improved a lot over the status quo ^^'
I intend to merge this after #155499. Split it off into a separate PR for ease of reviewing.