@@ -116,6 +116,8 @@ mod prim_bool { }
116
116
///
117
117
/// # `!` and generics
118
118
///
119
+ /// ## Infallible errors
120
+ ///
119
121
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
120
122
/// trait:
121
123
///
@@ -144,9 +146,60 @@ mod prim_bool { }
144
146
/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain
145
147
/// enum variants from generic types like `Result`.
146
148
///
149
+ /// ## Infinite loops
150
+ ///
151
+ /// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to remove
152
+ /// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not
153
+ /// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it
154
+ /// *has* errored.
155
+ ///
156
+ /// For example, consider the case of a simple web server, which can be simplified to:
157
+ ///
158
+ /// ```ignore (hypothetical-example)
159
+ /// loop {
160
+ /// let (client, request) = get_request().expect("disconnected");
161
+ /// let response = request.process();
162
+ /// response.send(client);
163
+ /// }
164
+ /// ```
165
+ ///
166
+ /// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection.
167
+ /// Instead, we'd like to keep track of this error, like this:
168
+ ///
169
+ /// ```ignore (hypothetical-example)
170
+ /// loop {
171
+ /// match get_request() {
172
+ /// Err(err) => break err,
173
+ /// Ok((client, request)) => {
174
+ /// let response = request.process();
175
+ /// response.send(client);
176
+ /// },
177
+ /// }
178
+ /// }
179
+ /// ```
180
+ ///
181
+ /// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it
182
+ /// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`]
183
+ /// instead:
184
+ ///
185
+ /// ```ignore (hypothetical-example)
186
+ /// fn server_loop() -> Result<!, ConnectionError> {
187
+ /// loop {
188
+ /// let (client, request) = get_request()?;
189
+ /// let response = request.process();
190
+ /// response.send(client);
191
+ /// }
192
+ /// }
193
+ /// ```
194
+ ///
195
+ /// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop
196
+ /// ever stops, it means that an error occurred. We don't even have to wrap the loop in an `Ok`
197
+ /// because `!` coerces to `Result<!, ConnectionError>` automatically.
198
+ ///
147
199
/// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str
148
200
/// [`Result<String, !>`]: result/enum.Result.html
149
201
/// [`Result<T, !>`]: result/enum.Result.html
202
+ /// [`Result<!, E>`]: result/enum.Result.html
150
203
/// [`Ok`]: result/enum.Result.html#variant.Ok
151
204
/// [`String`]: string/struct.String.html
152
205
/// [`Err`]: result/enum.Result.html#variant.Err
0 commit comments