@@ -112,6 +112,8 @@ mod prim_bool { }
112
112
///
113
113
/// # `!` and generics
114
114
///
115
+ /// ## Infalliable errors
116
+ ///
115
117
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
116
118
/// trait:
117
119
///
@@ -140,9 +142,59 @@ mod prim_bool { }
140
142
/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain
141
143
/// enum variants from generic types like `Result`.
142
144
///
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
+ ///
143
194
/// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str
144
195
/// [`Result<String, !>`]: result/enum.Result.html
145
196
/// [`Result<T, !>`]: result/enum.Result.html
197
+ /// [`Result<!, E>`]: result/enum.Result.html
146
198
/// [`Ok`]: result/enum.Result.html#variant.Ok
147
199
/// [`String`]: string/struct.String.html
148
200
/// [`Err`]: result/enum.Result.html#variant.Err
0 commit comments