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

``