]>
Commit | Line | Data |
---|---|---|
c34b1796 | 1 | //! Traits for working with Errors. |
c34b1796 AL |
2 | |
3 | #![stable(feature = "rust1", since = "1.0.0")] | |
4 | ||
5 | // A note about crates and the facade: | |
6 | // | |
7 | // Originally, the `Error` trait was defined in libcore, and the impls | |
8 | // were scattered about. However, coherence objected to this | |
9 | // arrangement, because to create the blanket impls for `Box` required | |
10 | // knowing that `&str: !Error`, and we have no means to deal with that | |
11 | // sort of conflict just now. Therefore, for the time being, we have | |
12 | // moved the `Error` trait into libstd. As we evolve a sol'n to the | |
13 | // coherence challenge (e.g., specialization, neg impls, etc) we can | |
14 | // reconsider what crate these items belong in. | |
15 | ||
1b1a35ee XL |
16 | #[cfg(test)] |
17 | mod tests; | |
18 | ||
abe05a73 | 19 | use core::array; |
f9f354fc | 20 | use core::convert::Infallible; |
532ac7d7 | 21 | |
fc512014 | 22 | use crate::alloc::{AllocError, LayoutError}; |
532ac7d7 | 23 | use crate::any::TypeId; |
e1599b0c | 24 | use crate::backtrace::Backtrace; |
532ac7d7 XL |
25 | use crate::borrow::Cow; |
26 | use crate::cell; | |
27 | use crate::char; | |
28 | use crate::fmt::{self, Debug, Display}; | |
29 | use crate::mem::transmute; | |
30 | use crate::num; | |
31 | use crate::str; | |
32 | use crate::string; | |
6a06907d | 33 | use crate::sync::Arc; |
c34b1796 | 34 | |
83c7162d | 35 | /// `Error` is a trait representing the basic expectations for error values, |
0731742a | 36 | /// i.e., values of type `E` in [`Result<T, E>`]. Errors must describe |
83c7162d XL |
37 | /// themselves through the [`Display`] and [`Debug`] traits, and may provide |
38 | /// cause chain information: | |
39 | /// | |
1b1a35ee XL |
40 | /// [`Error::source()`] is generally used when errors cross |
41 | /// "abstraction boundaries". If one module must report an error that is caused | |
42 | /// by an error from a lower-level module, it can allow accessing that error | |
43 | /// via [`Error::source()`]. This makes it possible for the high-level | |
44 | /// module to provide its own errors while also revealing some of the | |
45 | /// implementation for debugging via `source` chains. | |
c34b1796 | 46 | #[stable(feature = "rust1", since = "1.0.0")] |
9e0c209e | 47 | pub trait Error: Debug + Display { |
b7449926 XL |
48 | /// The lower-level source of this error, if any. |
49 | /// | |
50 | /// # Examples | |
51 | /// | |
52 | /// ``` | |
53 | /// use std::error::Error; | |
54 | /// use std::fmt; | |
55 | /// | |
56 | /// #[derive(Debug)] | |
57 | /// struct SuperError { | |
58 | /// side: SuperErrorSideKick, | |
59 | /// } | |
60 | /// | |
61 | /// impl fmt::Display for SuperError { | |
532ac7d7 | 62 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
b7449926 XL |
63 | /// write!(f, "SuperError is here!") |
64 | /// } | |
65 | /// } | |
66 | /// | |
67 | /// impl Error for SuperError { | |
b7449926 XL |
68 | /// fn source(&self) -> Option<&(dyn Error + 'static)> { |
69 | /// Some(&self.side) | |
70 | /// } | |
71 | /// } | |
72 | /// | |
73 | /// #[derive(Debug)] | |
74 | /// struct SuperErrorSideKick; | |
75 | /// | |
76 | /// impl fmt::Display for SuperErrorSideKick { | |
532ac7d7 | 77 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
b7449926 XL |
78 | /// write!(f, "SuperErrorSideKick is here!") |
79 | /// } | |
80 | /// } | |
81 | /// | |
dfeec247 | 82 | /// impl Error for SuperErrorSideKick {} |
b7449926 XL |
83 | /// |
84 | /// fn get_super_error() -> Result<(), SuperError> { | |
85 | /// Err(SuperError { side: SuperErrorSideKick }) | |
86 | /// } | |
87 | /// | |
88 | /// fn main() { | |
89 | /// match get_super_error() { | |
90 | /// Err(e) => { | |
ba9703b0 | 91 | /// println!("Error: {}", e); |
b7449926 XL |
92 | /// println!("Caused by: {}", e.source().unwrap()); |
93 | /// } | |
94 | /// _ => println!("No error"), | |
95 | /// } | |
96 | /// } | |
97 | /// ``` | |
98 | #[stable(feature = "error_source", since = "1.30.0")] | |
dfeec247 XL |
99 | fn source(&self) -> Option<&(dyn Error + 'static)> { |
100 | None | |
101 | } | |
bd371182 | 102 | |
e1599b0c | 103 | /// Gets the `TypeId` of `self`. |
bd371182 | 104 | #[doc(hidden)] |
dfeec247 XL |
105 | #[unstable( |
106 | feature = "error_type_id", | |
107 | reason = "this is memory-unsafe to override in user code", | |
108 | issue = "60784" | |
109 | )] | |
110 | fn type_id(&self, _: private::Internal) -> TypeId | |
111 | where | |
112 | Self: 'static, | |
113 | { | |
bd371182 AL |
114 | TypeId::of::<Self>() |
115 | } | |
e1599b0c | 116 | |
60c5eb7d | 117 | /// Returns a stack backtrace, if available, of where this error occurred. |
e1599b0c XL |
118 | /// |
119 | /// This function allows inspecting the location, in code, of where an error | |
120 | /// happened. The returned `Backtrace` contains information about the stack | |
121 | /// trace of the OS thread of execution of where the error originated from. | |
122 | /// | |
123 | /// Note that not all errors contain a `Backtrace`. Also note that a | |
124 | /// `Backtrace` may actually be empty. For more information consult the | |
125 | /// `Backtrace` type itself. | |
126 | #[unstable(feature = "backtrace", issue = "53487")] | |
127 | fn backtrace(&self) -> Option<&Backtrace> { | |
128 | None | |
129 | } | |
dfeec247 XL |
130 | |
131 | /// ``` | |
132 | /// if let Err(e) = "xc".parse::<u32>() { | |
133 | /// // Print `e` itself, no need for description(). | |
134 | /// eprintln!("Error: {}", e); | |
135 | /// } | |
136 | /// ``` | |
137 | #[stable(feature = "rust1", since = "1.0.0")] | |
138 | #[rustc_deprecated(since = "1.42.0", reason = "use the Display impl or to_string()")] | |
139 | fn description(&self) -> &str { | |
140 | "description() is deprecated; use Display" | |
141 | } | |
142 | ||
143 | #[stable(feature = "rust1", since = "1.0.0")] | |
144 | #[rustc_deprecated( | |
145 | since = "1.33.0", | |
146 | reason = "replaced by Error::source, which can support downcasting" | |
147 | )] | |
148 | #[allow(missing_docs)] | |
149 | fn cause(&self) -> Option<&dyn Error> { | |
150 | self.source() | |
151 | } | |
c34b1796 AL |
152 | } |
153 | ||
48663c56 XL |
154 | mod private { |
155 | // This is a hack to prevent `type_id` from being overridden by `Error` | |
156 | // implementations, since that can enable unsound downcasting. | |
157 | #[unstable(feature = "error_type_id", issue = "60784")] | |
158 | #[derive(Debug)] | |
159 | pub struct Internal; | |
160 | } | |
161 | ||
c34b1796 | 162 | #[stable(feature = "rust1", since = "1.0.0")] |
8faf50e0 | 163 | impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { |
0bf4aa26 XL |
164 | /// Converts a type of [`Error`] into a box of dyn [`Error`]. |
165 | /// | |
166 | /// # Examples | |
167 | /// | |
168 | /// ``` | |
169 | /// use std::error::Error; | |
170 | /// use std::fmt; | |
171 | /// use std::mem; | |
172 | /// | |
173 | /// #[derive(Debug)] | |
174 | /// struct AnError; | |
175 | /// | |
176 | /// impl fmt::Display for AnError { | |
532ac7d7 | 177 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0bf4aa26 XL |
178 | /// write!(f , "An error") |
179 | /// } | |
180 | /// } | |
181 | /// | |
dfeec247 | 182 | /// impl Error for AnError {} |
0bf4aa26 XL |
183 | /// |
184 | /// let an_error = AnError; | |
185 | /// assert!(0 == mem::size_of_val(&an_error)); | |
dc9dc135 | 186 | /// let a_boxed_error = Box::<dyn Error>::from(an_error); |
0bf4aa26 XL |
187 | /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error)) |
188 | /// ``` | |
8faf50e0 | 189 | fn from(err: E) -> Box<dyn Error + 'a> { |
c34b1796 AL |
190 | Box::new(err) |
191 | } | |
192 | } | |
193 | ||
194 | #[stable(feature = "rust1", since = "1.0.0")] | |
8faf50e0 | 195 | impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> { |
e74abb32 XL |
196 | /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of |
197 | /// dyn [`Error`] + [`Send`] + [`Sync`]. | |
0bf4aa26 XL |
198 | /// |
199 | /// # Examples | |
200 | /// | |
201 | /// ``` | |
202 | /// use std::error::Error; | |
203 | /// use std::fmt; | |
204 | /// use std::mem; | |
205 | /// | |
206 | /// #[derive(Debug)] | |
207 | /// struct AnError; | |
208 | /// | |
209 | /// impl fmt::Display for AnError { | |
532ac7d7 | 210 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
0bf4aa26 XL |
211 | /// write!(f , "An error") |
212 | /// } | |
213 | /// } | |
214 | /// | |
dfeec247 | 215 | /// impl Error for AnError {} |
0bf4aa26 XL |
216 | /// |
217 | /// unsafe impl Send for AnError {} | |
218 | /// | |
219 | /// unsafe impl Sync for AnError {} | |
220 | /// | |
221 | /// let an_error = AnError; | |
222 | /// assert!(0 == mem::size_of_val(&an_error)); | |
dc9dc135 | 223 | /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error); |
0bf4aa26 XL |
224 | /// assert!( |
225 | /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error)) | |
226 | /// ``` | |
8faf50e0 | 227 | fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> { |
c34b1796 AL |
228 | Box::new(err) |
229 | } | |
230 | } | |
231 | ||
232 | #[stable(feature = "rust1", since = "1.0.0")] | |
8faf50e0 | 233 | impl From<String> for Box<dyn Error + Send + Sync> { |
e74abb32 | 234 | /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. |
0bf4aa26 XL |
235 | /// |
236 | /// # Examples | |
237 | /// | |
238 | /// ``` | |
239 | /// use std::error::Error; | |
240 | /// use std::mem; | |
241 | /// | |
242 | /// let a_string_error = "a string error".to_string(); | |
dc9dc135 | 243 | /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error); |
0bf4aa26 XL |
244 | /// assert!( |
245 | /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error)) | |
246 | /// ``` | |
dfeec247 | 247 | #[inline] |
8faf50e0 | 248 | fn from(err: String) -> Box<dyn Error + Send + Sync> { |
c34b1796 AL |
249 | struct StringError(String); |
250 | ||
251 | impl Error for StringError { | |
dfeec247 XL |
252 | #[allow(deprecated)] |
253 | fn description(&self) -> &str { | |
254 | &self.0 | |
255 | } | |
c34b1796 AL |
256 | } |
257 | ||
258 | impl Display for StringError { | |
532ac7d7 | 259 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
c34b1796 AL |
260 | Display::fmt(&self.0, f) |
261 | } | |
262 | } | |
263 | ||
dc9dc135 XL |
264 | // Purposefully skip printing "StringError(..)" |
265 | impl Debug for StringError { | |
266 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
267 | Debug::fmt(&self.0, f) | |
268 | } | |
269 | } | |
270 | ||
9346a6ac AL |
271 | Box::new(StringError(err)) |
272 | } | |
273 | } | |
274 | ||
7cac9316 | 275 | #[stable(feature = "string_box_error", since = "1.6.0")] |
8faf50e0 | 276 | impl From<String> for Box<dyn Error> { |
0bf4aa26 XL |
277 | /// Converts a [`String`] into a box of dyn [`Error`]. |
278 | /// | |
279 | /// # Examples | |
280 | /// | |
281 | /// ``` | |
282 | /// use std::error::Error; | |
283 | /// use std::mem; | |
284 | /// | |
285 | /// let a_string_error = "a string error".to_string(); | |
dc9dc135 | 286 | /// let a_boxed_error = Box::<dyn Error>::from(a_string_error); |
0bf4aa26 XL |
287 | /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error)) |
288 | /// ``` | |
8faf50e0 XL |
289 | fn from(str_err: String) -> Box<dyn Error> { |
290 | let err1: Box<dyn Error + Send + Sync> = From::from(str_err); | |
291 | let err2: Box<dyn Error> = err1; | |
92a42be0 SL |
292 | err2 |
293 | } | |
294 | } | |
295 | ||
9346a6ac | 296 | #[stable(feature = "rust1", since = "1.0.0")] |
532ac7d7 | 297 | impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> { |
e74abb32 | 298 | /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. |
0bf4aa26 | 299 | /// |
3dfed10e | 300 | /// [`str`]: prim@str |
48663c56 | 301 | /// |
0bf4aa26 XL |
302 | /// # Examples |
303 | /// | |
304 | /// ``` | |
305 | /// use std::error::Error; | |
306 | /// use std::mem; | |
307 | /// | |
308 | /// let a_str_error = "a str error"; | |
dc9dc135 | 309 | /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error); |
0bf4aa26 XL |
310 | /// assert!( |
311 | /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error)) | |
312 | /// ``` | |
dfeec247 | 313 | #[inline] |
532ac7d7 | 314 | fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> { |
62682a34 | 315 | From::from(String::from(err)) |
c34b1796 AL |
316 | } |
317 | } | |
318 | ||
7cac9316 | 319 | #[stable(feature = "string_box_error", since = "1.6.0")] |
532ac7d7 | 320 | impl From<&str> for Box<dyn Error> { |
0bf4aa26 XL |
321 | /// Converts a [`str`] into a box of dyn [`Error`]. |
322 | /// | |
3dfed10e | 323 | /// [`str`]: prim@str |
48663c56 | 324 | /// |
0bf4aa26 XL |
325 | /// # Examples |
326 | /// | |
327 | /// ``` | |
328 | /// use std::error::Error; | |
329 | /// use std::mem; | |
330 | /// | |
331 | /// let a_str_error = "a str error"; | |
dc9dc135 | 332 | /// let a_boxed_error = Box::<dyn Error>::from(a_str_error); |
0bf4aa26 XL |
333 | /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error)) |
334 | /// ``` | |
532ac7d7 | 335 | fn from(err: &str) -> Box<dyn Error> { |
92a42be0 SL |
336 | From::from(String::from(err)) |
337 | } | |
338 | } | |
339 | ||
ea8adc8c | 340 | #[stable(feature = "cow_box_error", since = "1.22.0")] |
8faf50e0 | 341 | impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { |
e74abb32 | 342 | /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. |
0bf4aa26 XL |
343 | /// |
344 | /// # Examples | |
345 | /// | |
346 | /// ``` | |
347 | /// use std::error::Error; | |
348 | /// use std::mem; | |
349 | /// use std::borrow::Cow; | |
350 | /// | |
351 | /// let a_cow_str_error = Cow::from("a str error"); | |
dc9dc135 | 352 | /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error); |
0bf4aa26 XL |
353 | /// assert!( |
354 | /// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error)) | |
355 | /// ``` | |
8faf50e0 | 356 | fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> { |
ea8adc8c XL |
357 | From::from(String::from(err)) |
358 | } | |
359 | } | |
360 | ||
361 | #[stable(feature = "cow_box_error", since = "1.22.0")] | |
8faf50e0 | 362 | impl<'a> From<Cow<'a, str>> for Box<dyn Error> { |
0bf4aa26 XL |
363 | /// Converts a [`Cow`] into a box of dyn [`Error`]. |
364 | /// | |
365 | /// # Examples | |
366 | /// | |
367 | /// ``` | |
368 | /// use std::error::Error; | |
369 | /// use std::mem; | |
370 | /// use std::borrow::Cow; | |
371 | /// | |
372 | /// let a_cow_str_error = Cow::from("a str error"); | |
dc9dc135 | 373 | /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error); |
0bf4aa26 XL |
374 | /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error)) |
375 | /// ``` | |
8faf50e0 | 376 | fn from(err: Cow<'a, str>) -> Box<dyn Error> { |
ea8adc8c XL |
377 | From::from(String::from(err)) |
378 | } | |
379 | } | |
380 | ||
ff7c6d11 | 381 | #[unstable(feature = "never_type", issue = "35121")] |
dfeec247 XL |
382 | impl Error for ! {} |
383 | ||
384 | #[unstable( | |
385 | feature = "allocator_api", | |
386 | reason = "the precise API and guarantees it provides may be tweaked.", | |
387 | issue = "32838" | |
388 | )] | |
1b1a35ee | 389 | impl Error for AllocError {} |
dfeec247 | 390 | |
1b1a35ee | 391 | #[stable(feature = "alloc_layout", since = "1.28.0")] |
fc512014 | 392 | impl Error for LayoutError {} |
dfeec247 | 393 | |
c34b1796 AL |
394 | #[stable(feature = "rust1", since = "1.0.0")] |
395 | impl Error for str::ParseBoolError { | |
dfeec247 XL |
396 | #[allow(deprecated)] |
397 | fn description(&self) -> &str { | |
398 | "failed to parse bool" | |
399 | } | |
c34b1796 AL |
400 | } |
401 | ||
402 | #[stable(feature = "rust1", since = "1.0.0")] | |
403 | impl Error for str::Utf8Error { | |
dfeec247 | 404 | #[allow(deprecated)] |
c34b1796 | 405 | fn description(&self) -> &str { |
9346a6ac | 406 | "invalid utf-8: corrupt contents" |
c34b1796 AL |
407 | } |
408 | } | |
409 | ||
410 | #[stable(feature = "rust1", since = "1.0.0")] | |
411 | impl Error for num::ParseIntError { | |
dfeec247 | 412 | #[allow(deprecated)] |
c34b1796 | 413 | fn description(&self) -> &str { |
62682a34 | 414 | self.__description() |
c34b1796 AL |
415 | } |
416 | } | |
417 | ||
9fa01778 | 418 | #[stable(feature = "try_from", since = "1.34.0")] |
a7813a04 | 419 | impl Error for num::TryFromIntError { |
dfeec247 | 420 | #[allow(deprecated)] |
a7813a04 XL |
421 | fn description(&self) -> &str { |
422 | self.__description() | |
423 | } | |
424 | } | |
425 | ||
9fa01778 | 426 | #[stable(feature = "try_from", since = "1.34.0")] |
abe05a73 | 427 | impl Error for array::TryFromSliceError { |
dfeec247 | 428 | #[allow(deprecated)] |
abe05a73 XL |
429 | fn description(&self) -> &str { |
430 | self.__description() | |
431 | } | |
432 | } | |
433 | ||
c34b1796 AL |
434 | #[stable(feature = "rust1", since = "1.0.0")] |
435 | impl Error for num::ParseFloatError { | |
dfeec247 | 436 | #[allow(deprecated)] |
c34b1796 | 437 | fn description(&self) -> &str { |
d9579d0f | 438 | self.__description() |
c34b1796 AL |
439 | } |
440 | } | |
441 | ||
442 | #[stable(feature = "rust1", since = "1.0.0")] | |
443 | impl Error for string::FromUtf8Error { | |
dfeec247 | 444 | #[allow(deprecated)] |
c34b1796 AL |
445 | fn description(&self) -> &str { |
446 | "invalid utf-8" | |
447 | } | |
448 | } | |
449 | ||
450 | #[stable(feature = "rust1", since = "1.0.0")] | |
451 | impl Error for string::FromUtf16Error { | |
dfeec247 | 452 | #[allow(deprecated)] |
c34b1796 AL |
453 | fn description(&self) -> &str { |
454 | "invalid utf-16" | |
455 | } | |
456 | } | |
457 | ||
7453a54e | 458 | #[stable(feature = "str_parse_error2", since = "1.8.0")] |
f9f354fc | 459 | impl Error for Infallible { |
7453a54e SL |
460 | fn description(&self) -> &str { |
461 | match *self {} | |
462 | } | |
463 | } | |
464 | ||
54a0048b SL |
465 | #[stable(feature = "decode_utf16", since = "1.9.0")] |
466 | impl Error for char::DecodeUtf16Error { | |
dfeec247 | 467 | #[allow(deprecated)] |
54a0048b SL |
468 | fn description(&self) -> &str { |
469 | "unpaired surrogate found" | |
470 | } | |
471 | } | |
472 | ||
6a06907d XL |
473 | #[unstable(feature = "map_try_insert", issue = "82766")] |
474 | impl<'a, K: Debug + Ord, V: Debug> Error | |
475 | for crate::collections::btree_map::OccupiedError<'a, K, V> | |
476 | { | |
477 | #[allow(deprecated)] | |
478 | fn description(&self) -> &str { | |
479 | "key already exists" | |
480 | } | |
481 | } | |
482 | ||
483 | #[unstable(feature = "map_try_insert", issue = "82766")] | |
484 | impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> { | |
485 | #[allow(deprecated)] | |
486 | fn description(&self) -> &str { | |
487 | "key already exists" | |
488 | } | |
489 | } | |
490 | ||
7cac9316 | 491 | #[stable(feature = "box_error", since = "1.8.0")] |
7453a54e | 492 | impl<T: Error> Error for Box<T> { |
dfeec247 | 493 | #[allow(deprecated, deprecated_in_future)] |
7453a54e SL |
494 | fn description(&self) -> &str { |
495 | Error::description(&**self) | |
496 | } | |
497 | ||
0731742a | 498 | #[allow(deprecated)] |
8faf50e0 | 499 | fn cause(&self) -> Option<&dyn Error> { |
7453a54e SL |
500 | Error::cause(&**self) |
501 | } | |
dc9dc135 XL |
502 | |
503 | fn source(&self) -> Option<&(dyn Error + 'static)> { | |
504 | Error::source(&**self) | |
505 | } | |
7453a54e SL |
506 | } |
507 | ||
5869c6ff XL |
508 | #[stable(feature = "error_by_ref", since = "1.51.0")] |
509 | impl<'a, T: Error + ?Sized> Error for &'a T { | |
510 | #[allow(deprecated, deprecated_in_future)] | |
511 | fn description(&self) -> &str { | |
512 | Error::description(&**self) | |
513 | } | |
514 | ||
515 | #[allow(deprecated)] | |
516 | fn cause(&self) -> Option<&dyn Error> { | |
517 | Error::cause(&**self) | |
518 | } | |
519 | ||
520 | fn source(&self) -> Option<&(dyn Error + 'static)> { | |
521 | Error::source(&**self) | |
522 | } | |
523 | ||
524 | fn backtrace(&self) -> Option<&Backtrace> { | |
525 | Error::backtrace(&**self) | |
526 | } | |
527 | } | |
528 | ||
6a06907d XL |
529 | #[stable(feature = "arc_error", since = "1.52.0")] |
530 | impl<T: Error + ?Sized> Error for Arc<T> { | |
531 | #[allow(deprecated, deprecated_in_future)] | |
532 | fn description(&self) -> &str { | |
533 | Error::description(&**self) | |
534 | } | |
535 | ||
536 | #[allow(deprecated)] | |
537 | fn cause(&self) -> Option<&dyn Error> { | |
538 | Error::cause(&**self) | |
539 | } | |
540 | ||
541 | fn source(&self) -> Option<&(dyn Error + 'static)> { | |
542 | Error::source(&**self) | |
543 | } | |
544 | ||
545 | fn backtrace(&self) -> Option<&Backtrace> { | |
546 | Error::backtrace(&**self) | |
547 | } | |
548 | } | |
549 | ||
3157f602 XL |
550 | #[stable(feature = "fmt_error", since = "1.11.0")] |
551 | impl Error for fmt::Error { | |
dfeec247 | 552 | #[allow(deprecated)] |
3157f602 XL |
553 | fn description(&self) -> &str { |
554 | "an error occurred when formatting an argument" | |
555 | } | |
556 | } | |
557 | ||
9e0c209e SL |
558 | #[stable(feature = "try_borrow", since = "1.13.0")] |
559 | impl Error for cell::BorrowError { | |
dfeec247 | 560 | #[allow(deprecated)] |
5bcae85e SL |
561 | fn description(&self) -> &str { |
562 | "already mutably borrowed" | |
563 | } | |
564 | } | |
565 | ||
9e0c209e SL |
566 | #[stable(feature = "try_borrow", since = "1.13.0")] |
567 | impl Error for cell::BorrowMutError { | |
dfeec247 | 568 | #[allow(deprecated)] |
5bcae85e SL |
569 | fn description(&self) -> &str { |
570 | "already borrowed" | |
571 | } | |
572 | } | |
573 | ||
9fa01778 | 574 | #[stable(feature = "try_from", since = "1.34.0")] |
9e0c209e | 575 | impl Error for char::CharTryFromError { |
dfeec247 | 576 | #[allow(deprecated)] |
9e0c209e SL |
577 | fn description(&self) -> &str { |
578 | "converted integer out of range for `char`" | |
579 | } | |
580 | } | |
581 | ||
041b39d2 XL |
582 | #[stable(feature = "char_from_str", since = "1.20.0")] |
583 | impl Error for char::ParseCharError { | |
dfeec247 | 584 | #[allow(deprecated)] |
041b39d2 XL |
585 | fn description(&self) -> &str { |
586 | self.__description() | |
587 | } | |
588 | } | |
589 | ||
ba9703b0 XL |
590 | #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] |
591 | impl Error for alloc::collections::TryReserveError {} | |
592 | ||
e1599b0c | 593 | // Copied from `any.rs`. |
8faf50e0 | 594 | impl dyn Error + 'static { |
9fa01778 | 595 | /// Returns `true` if the boxed type is the same as `T` |
c1a9b12d | 596 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
597 | #[inline] |
598 | pub fn is<T: Error + 'static>(&self) -> bool { | |
e1599b0c | 599 | // Get `TypeId` of the type this function is instantiated with. |
bd371182 AL |
600 | let t = TypeId::of::<T>(); |
601 | ||
e1599b0c | 602 | // Get `TypeId` of the type in the trait object. |
48663c56 | 603 | let boxed = self.type_id(private::Internal); |
bd371182 | 604 | |
e1599b0c | 605 | // Compare both `TypeId`s on equality. |
bd371182 AL |
606 | t == boxed |
607 | } | |
608 | ||
609 | /// Returns some reference to the boxed value if it is of type `T`, or | |
610 | /// `None` if it isn't. | |
c1a9b12d | 611 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
612 | #[inline] |
613 | pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { | |
614 | if self.is::<T>() { | |
dfeec247 | 615 | unsafe { Some(&*(self as *const dyn Error as *const T)) } |
bd371182 AL |
616 | } else { |
617 | None | |
618 | } | |
619 | } | |
620 | ||
621 | /// Returns some mutable reference to the boxed value if it is of type `T`, or | |
622 | /// `None` if it isn't. | |
c1a9b12d | 623 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
624 | #[inline] |
625 | pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { | |
626 | if self.is::<T>() { | |
dfeec247 | 627 | unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) } |
bd371182 AL |
628 | } else { |
629 | None | |
630 | } | |
631 | } | |
632 | } | |
633 | ||
8faf50e0 | 634 | impl dyn Error + 'static + Send { |
e1599b0c | 635 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d | 636 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
637 | #[inline] |
638 | pub fn is<T: Error + 'static>(&self) -> bool { | |
8faf50e0 | 639 | <dyn Error + 'static>::is::<T>(self) |
bd371182 AL |
640 | } |
641 | ||
e1599b0c | 642 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d | 643 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
644 | #[inline] |
645 | pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { | |
8faf50e0 | 646 | <dyn Error + 'static>::downcast_ref::<T>(self) |
bd371182 AL |
647 | } |
648 | ||
e1599b0c | 649 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d SL |
650 | #[stable(feature = "error_downcast", since = "1.3.0")] |
651 | #[inline] | |
652 | pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { | |
8faf50e0 | 653 | <dyn Error + 'static>::downcast_mut::<T>(self) |
c1a9b12d SL |
654 | } |
655 | } | |
656 | ||
8faf50e0 | 657 | impl dyn Error + 'static + Send + Sync { |
e1599b0c | 658 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d SL |
659 | #[stable(feature = "error_downcast", since = "1.3.0")] |
660 | #[inline] | |
661 | pub fn is<T: Error + 'static>(&self) -> bool { | |
8faf50e0 | 662 | <dyn Error + 'static>::is::<T>(self) |
c1a9b12d SL |
663 | } |
664 | ||
e1599b0c | 665 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d SL |
666 | #[stable(feature = "error_downcast", since = "1.3.0")] |
667 | #[inline] | |
668 | pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { | |
8faf50e0 | 669 | <dyn Error + 'static>::downcast_ref::<T>(self) |
c1a9b12d SL |
670 | } |
671 | ||
e1599b0c | 672 | /// Forwards to the method defined on the type `dyn Error`. |
c1a9b12d | 673 | #[stable(feature = "error_downcast", since = "1.3.0")] |
bd371182 AL |
674 | #[inline] |
675 | pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { | |
8faf50e0 | 676 | <dyn Error + 'static>::downcast_mut::<T>(self) |
bd371182 AL |
677 | } |
678 | } | |
679 | ||
8faf50e0 | 680 | impl dyn Error { |
bd371182 | 681 | #[inline] |
c1a9b12d | 682 | #[stable(feature = "error_downcast", since = "1.3.0")] |
e1599b0c | 683 | /// Attempts to downcast the box to a concrete type. |
8faf50e0 | 684 | pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> { |
bd371182 AL |
685 | if self.is::<T>() { |
686 | unsafe { | |
8faf50e0 | 687 | let raw: *mut dyn Error = Box::into_raw(self); |
9e0c209e | 688 | Ok(Box::from_raw(raw as *mut T)) |
bd371182 AL |
689 | } |
690 | } else { | |
691 | Err(self) | |
692 | } | |
693 | } | |
9fa01778 XL |
694 | |
695 | /// Returns an iterator starting with the current error and continuing with | |
1b1a35ee | 696 | /// recursively calling [`Error::source`]. |
9fa01778 | 697 | /// |
60c5eb7d XL |
698 | /// If you want to omit the current error and only use its sources, |
699 | /// use `skip(1)`. | |
700 | /// | |
9fa01778 XL |
701 | /// # Examples |
702 | /// | |
703 | /// ``` | |
704 | /// #![feature(error_iter)] | |
705 | /// use std::error::Error; | |
706 | /// use std::fmt; | |
707 | /// | |
708 | /// #[derive(Debug)] | |
709 | /// struct A; | |
710 | /// | |
711 | /// #[derive(Debug)] | |
712 | /// struct B(Option<Box<dyn Error + 'static>>); | |
713 | /// | |
714 | /// impl fmt::Display for A { | |
532ac7d7 | 715 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
9fa01778 XL |
716 | /// write!(f, "A") |
717 | /// } | |
718 | /// } | |
719 | /// | |
720 | /// impl fmt::Display for B { | |
532ac7d7 | 721 | /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
9fa01778 XL |
722 | /// write!(f, "B") |
723 | /// } | |
724 | /// } | |
725 | /// | |
726 | /// impl Error for A {} | |
727 | /// | |
728 | /// impl Error for B { | |
729 | /// fn source(&self) -> Option<&(dyn Error + 'static)> { | |
730 | /// self.0.as_ref().map(|e| e.as_ref()) | |
731 | /// } | |
732 | /// } | |
733 | /// | |
734 | /// let b = B(Some(Box::new(A))); | |
735 | /// | |
736 | /// // let err : Box<Error> = b.into(); // or | |
737 | /// let err = &b as &(dyn Error); | |
738 | /// | |
60c5eb7d | 739 | /// let mut iter = err.chain(); |
9fa01778 XL |
740 | /// |
741 | /// assert_eq!("B".to_string(), iter.next().unwrap().to_string()); | |
742 | /// assert_eq!("A".to_string(), iter.next().unwrap().to_string()); | |
743 | /// assert!(iter.next().is_none()); | |
744 | /// assert!(iter.next().is_none()); | |
745 | /// ``` | |
9fa01778 XL |
746 | #[unstable(feature = "error_iter", issue = "58520")] |
747 | #[inline] | |
60c5eb7d | 748 | pub fn chain(&self) -> Chain<'_> { |
dfeec247 | 749 | Chain { current: Some(self) } |
9fa01778 | 750 | } |
9fa01778 XL |
751 | } |
752 | ||
60c5eb7d XL |
753 | /// An iterator over an [`Error`] and its sources. |
754 | /// | |
755 | /// If you want to omit the initial error and only process | |
756 | /// its sources, use `skip(1)`. | |
9fa01778 | 757 | #[unstable(feature = "error_iter", issue = "58520")] |
60c5eb7d XL |
758 | #[derive(Clone, Debug)] |
759 | pub struct Chain<'a> { | |
9fa01778 XL |
760 | current: Option<&'a (dyn Error + 'static)>, |
761 | } | |
762 | ||
763 | #[unstable(feature = "error_iter", issue = "58520")] | |
60c5eb7d | 764 | impl<'a> Iterator for Chain<'a> { |
9fa01778 XL |
765 | type Item = &'a (dyn Error + 'static); |
766 | ||
767 | fn next(&mut self) -> Option<Self::Item> { | |
768 | let current = self.current; | |
769 | self.current = self.current.and_then(Error::source); | |
770 | current | |
771 | } | |
bd371182 AL |
772 | } |
773 | ||
8faf50e0 | 774 | impl dyn Error + Send { |
bd371182 | 775 | #[inline] |
c1a9b12d | 776 | #[stable(feature = "error_downcast", since = "1.3.0")] |
e1599b0c | 777 | /// Attempts to downcast the box to a concrete type. |
dfeec247 | 778 | pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> { |
8faf50e0 XL |
779 | let err: Box<dyn Error> = self; |
780 | <dyn Error>::downcast(err).map_err(|s| unsafe { | |
e1599b0c | 781 | // Reapply the `Send` marker. |
8faf50e0 | 782 | transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s) |
bd371182 AL |
783 | }) |
784 | } | |
785 | } | |
c1a9b12d | 786 | |
8faf50e0 | 787 | impl dyn Error + Send + Sync { |
c1a9b12d SL |
788 | #[inline] |
789 | #[stable(feature = "error_downcast", since = "1.3.0")] | |
e1599b0c | 790 | /// Attempts to downcast the box to a concrete type. |
dfeec247 | 791 | pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> { |
8faf50e0 XL |
792 | let err: Box<dyn Error> = self; |
793 | <dyn Error>::downcast(err).map_err(|s| unsafe { | |
e1599b0c | 794 | // Reapply the `Send + Sync` marker. |
8faf50e0 | 795 | transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s) |
c1a9b12d SL |
796 | }) |
797 | } | |
798 | } |