Don't use T
with both Result and Option, improve explanation. · model-checking/verify-rust-std@f84d57f (original) (raw)
1
1
`` //! Error handling with the Result
type.
``
2
2
`//!
`
3
3
`` //! [Result<T, E>
][Result
] is the type used for returning and propagating
``
4
``
`` -
//! errors. It is an enum with the variants, [Ok(T)
], representing
``
5
``
`` -
//! success and containing a value, and [Err(E)
], representing error
``
6
``
`-
//! and containing an error value.
`
``
4
`` +
//! errors. It is an enum with the variants, [Ok(T)
], representing success and
``
``
5
`` +
//! containing a value, and [Err(E)
], representing error and containing an
``
``
6
`+
//! error value.
`
7
7
`//!
`
8
8
```` //! ```
`9`
`9`
`//! # #[allow(dead_code)]
`
`@@ -13,12 +13,11 @@
`
`13`
`13`
`//! }
`
`14`
`14`
```` //! ```
15
15
`//!
`
16
``
`` -
//! Functions return [Result
] whenever errors are expected and
``
17
``
`` -
//! recoverable. In the std
crate, [Result
] is most prominently used
``
18
``
`-
//! for I/O.
`
``
16
`` +
//! Functions return [Result
] whenever errors are expected and recoverable. In
``
``
17
`` +
//! the std
crate, [Result
] is most prominently used for
``
``
18
`+
//! I/O.
`
19
19
`//!
`
20
``
`` -
//! A simple function returning [Result
] might be
``
21
``
`-
//! defined and used like so:
`
``
20
`` +
//! A simple function returning [Result
] might be defined and used like so:
``
22
21
`//!
`
23
22
```` //! ```
`24`
`23`
`//! #[derive(Debug)]
`
`@@ -40,9 +39,9 @@
`
`40`
`39`
`//! }
`
`41`
`40`
```` //! ```
42
41
`//!
`
43
``
`` -
//! Pattern matching on [Result
]s is clear and straightforward for
``
44
``
`` -
//! simple cases, but [Result
] comes with some convenience methods
``
45
``
`-
//! that make working with it more succinct.
`
``
42
`` +
//! Pattern matching on [Result
]s is clear and straightforward for simple
``
``
43
`` +
//! cases, but [Result
] comes with some convenience methods that make working
``
``
44
`+
//! with it more succinct.
`
46
45
`//!
`
47
46
```` //! ```
`48`
`47`
`//! let good_result: Result<i32, i32> = Ok(10);
`
`@@ -68,16 +67,15 @@
`
`68`
`67`
`//!
`
`69`
`68`
`//! # Results must be used
`
`70`
`69`
`//!
`
`71`
``
`-
//! A common problem with using return values to indicate errors is
`
`72`
``
`-
//! that it is easy to ignore the return value, thus failing to handle
`
`73`
``
`` -
//! the error. [`Result`] is annotated with the `#[must_use]` attribute,
``
`74`
``
`-
//! which will cause the compiler to issue a warning when a Result
`
`75`
``
`` -
//! value is ignored. This makes [`Result`] especially useful with
``
`76`
``
`-
//! functions that may encounter errors but don't otherwise return a
`
`77`
``
`-
//! useful value.
`
``
`70`
`+
//! A common problem with using return values to indicate errors is that it is
`
``
`71`
`+
//! easy to ignore the return value, thus failing to handle the error.
`
``
`72`
`` +
//! [`Result`] is annotated with the `#[must_use]` attribute, which will cause
``
``
`73`
`+
//! the compiler to issue a warning when a Result value is ignored. This makes
`
``
`74`
`` +
//! [`Result`] especially useful with functions that may encounter errors but
``
``
`75`
`+
//! don't otherwise return a useful value.
`
`78`
`76`
`//!
`
`79`
``
`` -
//! Consider the [`write_all`] method defined for I/O types
``
`80`
``
`` -
//! by the [`Write`] trait:
``
``
`77`
`` +
//! Consider the [`write_all`] method defined for I/O types by the [`Write`]
``
``
`78`
`+
//! trait:
`
`81`
`79`
`//!
`
`82`
`80`
```` //! ```
83
81
`//! use std::io;
`
`@@ -87,12 +85,11 @@
`
87
85
`//! }
`
88
86
```` //! ```
`89`
`87`
`//!
`
`90`
``
`` -
//! *Note: The actual definition of [`Write`] uses [`io::Result`], which
``
`91`
``
`-
//! is just a synonym for <code>[Result]<T, [io::Error]></code>.*
`
``
`88`
`` +
//! *Note: The actual definition of [`Write`] uses [`io::Result`], which is just
``
``
`89`
`+
//! a synonym for <code>[Result]<T, [io::Error]></code>.*
`
`92`
`90`
`//!
`
`93`
``
`-
//! This method doesn't produce a value, but the write may
`
`94`
``
`-
//! fail. It's crucial to handle the error case, and *not* write
`
`95`
``
`-
//! something like this:
`
``
`91`
`+
//! This method doesn't produce a value, but the write may fail. It's crucial to
`
``
`92`
`+
//! handle the error case, and *not* write something like this:
`
`96`
`93`
`//!
`
`97`
`94`
```` //! ```no_run
98
95
`//! # #![allow(unused_must_use)] // \o/
`
`@@ -105,12 +102,12 @@
`
105
102
`//! file.write_all(b"important message");
`
106
103
```` //! ```
`107`
`104`
`//!
`
`108`
``
`-
//! If you *do* write that in Rust, the compiler will give you a
`
`109`
``
`` -
//! warning (by default, controlled by the `unused_must_use` lint).
``
``
`105`
`+
//! If you *do* write that in Rust, the compiler will give you a warning (by
`
``
`106`
`` +
//! default, controlled by the `unused_must_use` lint).
``
`110`
`107`
`//!
`
`111`
``
`-
//! You might instead, if you don't want to handle the error, simply
`
`112`
``
`` -
//! assert success with [`expect`]. This will panic if the
``
`113`
``
`-
//! write fails, providing a marginally useful message indicating why:
`
``
`108`
`+
//! You might instead, if you don't want to handle the error, simply assert
`
``
`109`
`` +
//! success with [`expect`]. This will panic if the write fails, providing a
``
``
`110`
`+
//! marginally useful message indicating why:
`
`114`
`111`
`//!
`
`115`
`112`
```` //! ```no_run
116
113
`//! use std::fs::File;
`
145
142
`//!
`
146
143
`` //! # The question mark operator, ?
``
147
144
`//!
`
148
``
`-
//! When writing code that calls many functions that return the
`
149
``
`` -
//! [Result
] type, the error handling can be tedious. The question mark
``
150
``
`` -
//! operator, [?
], hides some of the boilerplate of propagating errors
``
151
``
`-
//! up the call stack.
`
``
145
`` +
//! When writing code that calls many functions that return the [Result
] type,
``
``
146
`` +
//! the error handling can be tedious. The question mark operator, [?
], hides
``
``
147
`+
//! some of the boilerplate of propagating errors up the call stack.
`
152
148
`//!
`
153
149
`//! It replaces this:
`
154
150
`//!
`
209
205
`//!
`
210
206
`//! It's much nicer!
`
211
207
`//!
`
212
``
`` -
//! Ending the expression with [?
] will result in the [Ok
]'s unwrapped value, unless the result
``
213
``
`` -
//! is [Err
], in which case [Err
] is returned early from the enclosing function.
``
``
208
`` +
//! Ending the expression with [?
] will result in the [Ok
]'s unwrapped
``
``
209
`` +
//! value, unless the result is [Err
], in which case [Err
] is returned early
``
``
210
`+
//! from the enclosing function.
`
214
211
`//!
`
215
``
`` -
//! [?
] can be used in functions that return [Result
] because of the
``
216
``
`` -
//! early return of [Err
] that it provides.
``
``
212
`` +
//! [?
] can be used in functions that return [Result
] because of the early
``
``
213
`` +
//! return of [Err
] that it provides.
``
217
214
`//!
`
218
215
`` //! [expect
]: Result::expect
``
219
216
`` //! [Write
]: ../../std/io/trait.Write.html "io::Write"
``
220
``
`` -
//! [write_all
]: ../../std/io/trait.Write.html#method.write_all "io::Write::write_all"
``
``
217
`` +
//! [write_all
]: ../../std/io/trait.Write.html#method.write_all
``
``
218
`+
//! "io::Write::write_all"
`
221
219
`` //! [io::Result
]: ../../std/io/type.Result.html "io::Result"
``
222
220
`` //! [?
]: crate::ops::Try
``
223
221
`` //! [Ok(T)
]: Ok
``
`@@ -227,27 +225,33 @@
`
227
225
`//! # Representation
`
228
226
`//!
`
229
227
`` //! In some cases, [Result<T, E>
] will gain the same size, alignment, and ABI
``
230
``
`` -
//! guarantees as [Option<T>
] has. One of either the T
or E
type must be a
``
231
``
`` -
//! type that qualifies for Option
guarantees, and the other type must meet
``
232
``
`-
//! all of the following conditions:
`
``
228
`` +
//! guarantees as [Option<U>
] has. One of either the T
or E
type must be a
``
``
229
`` +
//! type that qualifies for the Option
[representation guarantees][opt-rep],
``
``
230
`+
//! and the other type must meet all of the following conditions:
`
233
231
`//! * Is a zero-sized type with alignment 1 (a "1-ZST").
`
234
232
`//! * Has no fields.
`
235
233
`` //! * Does not have the #[non_exhaustive]
attribute.
``
236
234
`//!
`
237
``
`` -
//! For example, Result<NonZeroI32, ()>
or Result<(), NonZeroI32>
would both
``
238
``
`` -
//! have the same guarantees as Option<NonZeroI32>
. The only difference is the
``
239
``
`` -
//! implied semantics: Result<NonZeroI32, ()>
is "a non-zero success value"
``
240
``
`` -
//! while Result<(), NonZeroI32>
is "a non-zero error value".
``
``
235
`` +
//! For example, NonZeroI32
qualifies for the Option
representation
``
``
236
`` +
//! guarantees, and ()
is a zero-sized type with alignment 1, no fields, and
``
``
237
`` +
//! it isn't non_exhaustive
. This means that both Result<NonZeroI32, ()>
and
``
``
238
`` +
//! Result<(), NonZeroI32>
have the same size, alignment, and ABI guarantees
``
``
239
`` +
//! as Option<NonZeroI32>
. The only difference is the implied semantics:
``
``
240
`` +
//! * Option<NonZeroI32>
is "a non-zero i32 might be present"
``
``
241
`` +
//! * Result<NonZeroI32, ()>
is "a non-zero i32 success result, if any"
``
``
242
`` +
//! * Result<(), NonZeroI32>
is "a non-zero i32 error result, if any"
``
``
243
`+
//!
`
``
244
`+
//! [opt-rep]: ../option/index.html#representation "Option Representation"
`
241
245
`//!
`
242
246
`//! # Method overview
`
243
247
`//!
`
244
``
`` -
//! In addition to working with pattern matching, [Result
] provides a
``
245
``
`-
//! wide variety of different methods.
`
``
248
`` +
//! In addition to working with pattern matching, [Result
] provides a wide
``
``
249
`+
//! variety of different methods.
`
246
250
`//!
`
247
251
`//! ## Querying the variant
`
248
252
`//!
`
249
``
`` -
//! The [is_ok
] and [is_err
] methods return [true
] if the [Result
]
``
250
``
`` -
//! is [Ok
] or [Err
], respectively.
``
``
253
`` +
//! The [is_ok
] and [is_err
] methods return [true
] if the [Result
] is
``
``
254
`` +
//! [Ok
] or [Err
], respectively.
``
251
255
`//!
`
252
256
`` //! [is_err
]: Result::is_err
``
253
257
`` //! [is_ok
]: Result::is_ok
``
`@@ -257,8 +261,8 @@
`
257
261
`` //! * [as_ref
] converts from &Result<T, E>
to Result<&T, &E>
``
258
262
`` //! * [as_mut
] converts from &mut Result<T, E>
to Result<&mut T, &mut E>
``
259
263
`` //! * [as_deref
] converts from &Result<T, E>
to Result<&T::Target, &E>
``
260
``
`` -
//! * [as_deref_mut
] converts from &mut Result<T, E>
to
``
261
``
`` -
//! Result<&mut T::Target, &mut E>
``
``
264
`` +
//! * [as_deref_mut
] converts from &mut Result<T, E>
to `Result<&mut
``
``
265
`` +
//! T::Target, &mut E>`
``
262
266
`//!
`
263
267
`` //! [as_deref
]: Result::as_deref
``
264
268
`` //! [as_deref_mut
]: Result::as_deref_mut
``
`@@ -267,19 +271,18 @@
`
267
271
`//!
`
268
272
`//! ## Extracting contained values
`
269
273
`//!
`
270
``
`` -
//! These methods extract the contained value in a [Result<T, E>
] when it
``
271
``
`` -
//! is the [Ok
] variant. If the [Result
] is [Err
]:
``
``
274
`` +
//! These methods extract the contained value in a [Result<T, E>
] when it is
``
``
275
`` +
//! the [Ok
] variant. If the [Result
] is [Err
]:
``
272
276
`//!
`
273
277
`` //! * [expect
] panics with a provided custom message
``
274
278
`` //! * [unwrap
] panics with a generic message
``
275
279
`` //! * [unwrap_or
] returns the provided default value
``
276
``
`` -
//! * [unwrap_or_default
] returns the default value of the type T
``
277
``
`` -
//! (which must implement the [Default
] trait)
``
278
``
`` -
//! * [unwrap_or_else
] returns the result of evaluating the provided
``
279
``
`-
//! function
`
``
280
`` +
//! * [unwrap_or_default
] returns the default value of the type T
(which
``
``
281
`` +
//! must implement the [Default
] trait)
``
``
282
`` +
//! * [unwrap_or_else
] returns the result of evaluating the provided function
``
280
283
`//!
`
281
``
`` -
//! The panicking methods [expect
] and [unwrap
] require E
to
``
282
``
`` -
//! implement the [Debug
] trait.
``
``
284
`` +
//! The panicking methods [expect
] and [unwrap
] require E
to implement the
``
``
285
`` +
//! [Debug
] trait.
``
283
286
`//!
`
284
287
`` //! [Debug
]: crate::fmt::Debug
``
285
288
`` //! [expect
]: Result::expect
``
`@@ -288,9 +291,9 @@
`
288
291
`` //! [unwrap_or_default
]: Result::unwrap_or_default
``
289
292
`` //! [unwrap_or_else
]: Result::unwrap_or_else
``
290
293
`//!
`
291
``
`` -
//! These methods extract the contained value in a [Result<T, E>
] when it
``
292
``
`` -
//! is the [Err
] variant. They require T
to implement the [Debug
]
``
293
``
`` -
//! trait. If the [Result
] is [Ok
]:
``
``
294
`` +
//! These methods extract the contained value in a [Result<T, E>
] when it is
``
``
295
`` +
//! the [Err
] variant. They require T
to implement the [Debug
] trait. If
``
``
296
`` +
//! the [Result
] is [Ok
]:
``
294
297
`//!
`
295
298
`` //! * [expect_err
] panics with a provided custom message
``
296
299
`` //! * [unwrap_err
] panics with a generic message
``
`@@ -305,10 +308,10 @@
`
305
308
`//!
`
306
309
`` //! * [err
][Result::err] transforms [Result<T, E>
] into [Option<E>
],
``
307
310
`` //! mapping [Err(e)
] to [Some(e)
] and [Ok(v)
] to [None
]
``
308
``
`` -
//! * [ok
][Result::ok] transforms [Result<T, E>
] into [Option<T>
],
``
309
``
`` -
//! mapping [Ok(v)
] to [Some(v)
] and [Err(e)
] to [None
]
``
310
``
`` -
//! * [transpose
] transposes a [Result
] of an [Option
] into an
``
311
``
`` -
//! [Option
] of a [Result
]
``
``
311
`` +
//! * [ok
][Result::ok] transforms [Result<T, E>
] into [Option<T>
], mapping
``
``
312
`` +
//! [Ok(v)
] to [Some(v)
] and [Err(e)
] to [None
]
``
``
313
`` +
//! * [transpose
] transposes a [Result
] of an [Option
] into an [Option
]
``
``
314
`` +
//! of a [Result
]
``
312
315
`//!
`
313
316
`` // Do NOT add link reference definitions for err
or ok
, because they
``
314
317
`` // will generate numerous incorrect URLs for Err
and Ok
elsewhere, due
``