Skip to content

Commit 20a795e

Browse files
author
Clar Charr
committed
Mention Result<!, E> in never docs.
1 parent 7360d6d commit 20a795e

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

src/libstd/primitive_docs.rs

+52
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ mod prim_bool { }
112112
///
113113
/// # `!` and generics
114114
///
115+
/// ## Infalliable errors
116+
///
115117
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
116118
/// trait:
117119
///
@@ -140,9 +142,59 @@ mod prim_bool { }
140142
/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain
141143
/// enum variants from generic types like `Result`.
142144
///
145+
/// ## Infinite loops
146+
///
147+
/// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to removed
148+
/// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not
149+
/// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it
150+
/// *has* errored.
151+
///
152+
/// For example, consider the case of a simple web server, which can be simplified to:
153+
///
154+
/// ```ignore (hypothetical-example)
155+
/// loop {
156+
/// let (client, request) = get_request().expect("disconnected");
157+
/// let response = request.process();
158+
/// response.send(client);
159+
/// }
160+
/// ```
161+
///
162+
/// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection.
163+
/// Instead, we'd like to keep track of this error, like this:
164+
///
165+
/// ```ignore (hypothetical-example)
166+
/// loop {
167+
/// match get_request() {
168+
/// Err(err) => break err,
169+
/// Ok((client, request)) => {
170+
/// let response = request.process();
171+
/// response.send(client);
172+
/// },
173+
/// }
174+
/// }
175+
/// ```
176+
///
177+
/// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it
178+
/// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`]
179+
/// instead:
180+
///
181+
/// ```ignore (hypothetical-example)
182+
/// fn server_loop() -> Result<!, ConnectionError> {
183+
/// Ok(loop {
184+
/// let (client, request) = get_request()?;
185+
/// let response = request.process();
186+
/// response.send(client);
187+
/// })
188+
/// }
189+
/// ```
190+
///
191+
/// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop
192+
/// ever stops, it means that an error occurred.
193+
///
143194
/// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str
144195
/// [`Result<String, !>`]: result/enum.Result.html
145196
/// [`Result<T, !>`]: result/enum.Result.html
197+
/// [`Result<!, E>`]: result/enum.Result.html
146198
/// [`Ok`]: result/enum.Result.html#variant.Ok
147199
/// [`String`]: string/struct.String.html
148200
/// [`Err`]: result/enum.Result.html#variant.Err

0 commit comments

Comments
 (0)