diff options
| author | kennytm <kennytm@gmail.com> | 2018-05-09 17:25:04 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2018-05-09 17:25:04 +0800 |
| commit | bb690c600ca0b59afd1dde131057917211130700 (patch) | |
| tree | 3296e6146bcbcf556dfc9b550a06f11642161cf7 /src/libstd/primitive_docs.rs | |
| parent | 8e7f6dbdd720ebc48e6ef815ecb15fa5535e24cc (diff) | |
| parent | fc6d6c98dedca297c09016615011bee448e5e468 (diff) | |
| download | rust-bb690c600ca0b59afd1dde131057917211130700.tar.gz rust-bb690c600ca0b59afd1dde131057917211130700.zip | |
Rollup merge of #49988 - clarcharr:never_docs, r=steveklabnik
Mention Result<!, E> in never docs. Fixes #48096.
Diffstat (limited to 'src/libstd/primitive_docs.rs')
| -rw-r--r-- | src/libstd/primitive_docs.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 919d9648297..437d7d74cae 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -116,6 +116,8 @@ mod prim_bool { } /// /// # `!` and generics /// +/// ## Infallible errors +/// /// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] /// trait: /// @@ -144,9 +146,60 @@ mod prim_bool { } /// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain /// enum variants from generic types like `Result`. /// +/// ## Infinite loops +/// +/// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to remove +/// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not +/// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it +/// *has* errored. +/// +/// For example, consider the case of a simple web server, which can be simplified to: +/// +/// ```ignore (hypothetical-example) +/// loop { +/// let (client, request) = get_request().expect("disconnected"); +/// let response = request.process(); +/// response.send(client); +/// } +/// ``` +/// +/// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection. +/// Instead, we'd like to keep track of this error, like this: +/// +/// ```ignore (hypothetical-example) +/// loop { +/// match get_request() { +/// Err(err) => break err, +/// Ok((client, request)) => { +/// let response = request.process(); +/// response.send(client); +/// }, +/// } +/// } +/// ``` +/// +/// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it +/// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`] +/// instead: +/// +/// ```ignore (hypothetical-example) +/// fn server_loop() -> Result<!, ConnectionError> { +/// loop { +/// let (client, request) = get_request()?; +/// let response = request.process(); +/// response.send(client); +/// } +/// } +/// ``` +/// +/// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop +/// ever stops, it means that an error occurred. We don't even have to wrap the loop in an `Ok` +/// because `!` coerces to `Result<!, ConnectionError>` automatically. +/// /// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str /// [`Result<String, !>`]: result/enum.Result.html /// [`Result<T, !>`]: result/enum.Result.html +/// [`Result<!, E>`]: result/enum.Result.html /// [`Ok`]: result/enum.Result.html#variant.Ok /// [`String`]: string/struct.String.html /// [`Err`]: result/enum.Result.html#variant.Err |
