]> git.lizzy.rs Git - rust.git/blob - library/std/src/error.rs
Rollup merge of #98583 - joshtriplett:stabilize-windows-symlink-types, r=thomcc
[rust.git] / library / std / src / error.rs
1 //! Interfaces for working with Errors.
2 //!
3 //! # Error Handling In Rust
4 //!
5 //! The Rust language provides two complementary systems for constructing /
6 //! representing, reporting, propagating, reacting to, and discarding errors.
7 //! These responsibilities are collectively known as "error handling." The
8 //! components of the first system, the panic runtime and interfaces, are most
9 //! commonly used to represent bugs that have been detected in your program. The
10 //! components of the second system, `Result`, the error traits, and user
11 //! defined types, are used to represent anticipated runtime failure modes of
12 //! your program.
13 //!
14 //! ## The Panic Interfaces
15 //!
16 //! The following are the primary interfaces of the panic system and the
17 //! responsibilities they cover:
18 //!
19 //! * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
20 //! * [`PanicInfo`] (Reporting)
21 //! * [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting)
22 //! * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
23 //!
24 //! The following are the primary interfaces of the error system and the
25 //! responsibilities they cover:
26 //!
27 //! * [`Result`] (Propagating, Reacting)
28 //! * The [`Error`] trait (Reporting)
29 //! * User defined types (Constructing / Representing)
30 //! * [`match`] and [`downcast`] (Reacting)
31 //! * The question mark operator ([`?`]) (Propagating)
32 //! * The partially stable [`Try`] traits (Propagating, Constructing)
33 //! * [`Termination`] (Reporting)
34 //!
35 //! ## Converting Errors into Panics
36 //!
37 //! The panic and error systems are not entirely distinct. Often times errors
38 //! that are anticipated runtime failures in an API might instead represent bugs
39 //! to a caller. For these situations the standard library provides APIs for
40 //! constructing panics with an `Error` as it's source.
41 //!
42 //! * [`Result::unwrap`]
43 //! * [`Result::expect`]
44 //!
45 //! These functions are equivalent, they either return the inner value if the
46 //! `Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
47 //! as the source. The only difference between them is that with `expect` you
48 //! provide a panic error message to be printed alongside the source, whereas
49 //! `unwrap` has a default message indicating only that you unwraped an `Err`.
50 //!
51 //! Of the two, `expect` is generally preferred since its `msg` field allows you
52 //! to convey your intent and assumptions which makes tracking down the source
53 //! of a panic easier. `unwrap` on the other hand can still be a good fit in
54 //! situations where you can trivially show that a piece of code will never
55 //! panic, such as `"127.0.0.1".parse::<std::net::IpAddr>().unwrap()` or early
56 //! prototyping.
57 //!
58 //! # Common Message Styles
59 //!
60 //! There are two common styles for how people word `expect` messages. Using
61 //! the message to present information to users encountering a panic
62 //! ("expect as error message") or using the message to present information
63 //! to developers debugging the panic ("expect as precondition").
64 //!
65 //! In the former case the expect message is used to describe the error that
66 //! has occurred which is considered a bug. Consider the following example:
67 //!
68 //! ```should_panic
69 //! // Read environment variable, panic if it is not present
70 //! let path = std::env::var("IMPORTANT_PATH").unwrap();
71 //! ```
72 //!
73 //! In the "expect as error message" style we would use expect to describe
74 //! that the environment variable was not set when it should have been:
75 //!
76 //! ```should_panic
77 //! let path = std::env::var("IMPORTANT_PATH")
78 //!     .expect("env variable `IMPORTANT_PATH` is not set");
79 //! ```
80 //!
81 //! In the "expect as precondition" style, we would instead describe the
82 //! reason we _expect_ the `Result` should be `Ok`. With this style we would
83 //! prefer to write:
84 //!
85 //! ```should_panic
86 //! let path = std::env::var("IMPORTANT_PATH")
87 //!     .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
88 //! ```
89 //!
90 //! The "expect as error message" style does not work as well with the
91 //! default output of the std panic hooks, and often ends up repeating
92 //! information that is already communicated by the source error being
93 //! unwrapped:
94 //!
95 //! ```text
96 //! thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
97 //! ```
98 //!
99 //! In this example we end up mentioning that an env variable is not set,
100 //! followed by our source message that says the env is not present, the
101 //! only additional information we're communicating is the name of the
102 //! environment variable being checked.
103 //!
104 //! The "expect as precondition" style instead focuses on source code
105 //! readability, making it easier to understand what must have gone wrong in
106 //! situations where panics are being used to represent bugs exclusively.
107 //! Also, by framing our expect in terms of what "SHOULD" have happened to
108 //! prevent the source error, we end up introducing new information that is
109 //! independent from our source error.
110 //!
111 //! ```text
112 //! thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
113 //! ```
114 //!
115 //! In this example we are communicating not only the name of the
116 //! environment variable that should have been set, but also an explanation
117 //! for why it should have been set, and we let the source error display as
118 //! a clear contradiction to our expectation.
119 //!
120 //! **Hint**: If you're having trouble remembering how to phrase
121 //! expect-as-precondition style error messages remember to focus on the word
122 //! "should" as in "env variable should be set by blah" or "the given binary
123 //! should be available and executable by the current user".
124 //!
125 //! [`panic_any`]: crate::panic::panic_any
126 //! [`PanicInfo`]: crate::panic::PanicInfo
127 //! [`catch_unwind`]: crate::panic::catch_unwind
128 //! [`resume_unwind`]: crate::panic::resume_unwind
129 //! [`downcast`]: crate::error::Error
130 //! [`Termination`]: crate::process::Termination
131 //! [`Try`]: crate::ops::Try
132 //! [panic hook]: crate::panic::set_hook
133 //! [`set_hook`]: crate::panic::set_hook
134 //! [`take_hook`]: crate::panic::take_hook
135 //! [panic-handler]: <https://doc.rust-lang.org/nomicon/panic-handler.html>
136 //! [`match`]: ../../std/keyword.match.html
137 //! [`?`]: ../../std/result/index.html#the-question-mark-operator-
138
139 #![stable(feature = "rust1", since = "1.0.0")]
140
141 // A note about crates and the facade:
142 //
143 // Originally, the `Error` trait was defined in libcore, and the impls
144 // were scattered about. However, coherence objected to this
145 // arrangement, because to create the blanket impls for `Box` required
146 // knowing that `&str: !Error`, and we have no means to deal with that
147 // sort of conflict just now. Therefore, for the time being, we have
148 // moved the `Error` trait into libstd. As we evolve a sol'n to the
149 // coherence challenge (e.g., specialization, neg impls, etc) we can
150 // reconsider what crate these items belong in.
151
152 #[cfg(test)]
153 mod tests;
154
155 use core::array;
156 use core::convert::Infallible;
157
158 use crate::alloc::{AllocError, LayoutError};
159 use crate::any::{Demand, Provider, TypeId};
160 use crate::backtrace::Backtrace;
161 use crate::borrow::Cow;
162 use crate::cell;
163 use crate::char;
164 use crate::fmt::{self, Debug, Display, Write};
165 use crate::io;
166 use crate::mem::transmute;
167 use crate::num;
168 use crate::str;
169 use crate::string;
170 use crate::sync::Arc;
171 use crate::time;
172
173 /// `Error` is a trait representing the basic expectations for error values,
174 /// i.e., values of type `E` in [`Result<T, E>`].
175 ///
176 /// Errors must describe themselves through the [`Display`] and [`Debug`]
177 /// traits. Error messages are typically concise lowercase sentences without
178 /// trailing punctuation:
179 ///
180 /// ```
181 /// let err = "NaN".parse::<u32>().unwrap_err();
182 /// assert_eq!(err.to_string(), "invalid digit found in string");
183 /// ```
184 ///
185 /// Errors may provide cause chain information. [`Error::source()`] is generally
186 /// used when errors cross "abstraction boundaries". If one module must report
187 /// an error that is caused by an error from a lower-level module, it can allow
188 /// accessing that error via [`Error::source()`]. This makes it possible for the
189 /// high-level module to provide its own errors while also revealing some of the
190 /// implementation for debugging via `source` chains.
191 #[stable(feature = "rust1", since = "1.0.0")]
192 #[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
193 pub trait Error: Debug + Display {
194     /// The lower-level source of this error, if any.
195     ///
196     /// # Examples
197     ///
198     /// ```
199     /// use std::error::Error;
200     /// use std::fmt;
201     ///
202     /// #[derive(Debug)]
203     /// struct SuperError {
204     ///     source: SuperErrorSideKick,
205     /// }
206     ///
207     /// impl fmt::Display for SuperError {
208     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209     ///         write!(f, "SuperError is here!")
210     ///     }
211     /// }
212     ///
213     /// impl Error for SuperError {
214     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
215     ///         Some(&self.source)
216     ///     }
217     /// }
218     ///
219     /// #[derive(Debug)]
220     /// struct SuperErrorSideKick;
221     ///
222     /// impl fmt::Display for SuperErrorSideKick {
223     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224     ///         write!(f, "SuperErrorSideKick is here!")
225     ///     }
226     /// }
227     ///
228     /// impl Error for SuperErrorSideKick {}
229     ///
230     /// fn get_super_error() -> Result<(), SuperError> {
231     ///     Err(SuperError { source: SuperErrorSideKick })
232     /// }
233     ///
234     /// fn main() {
235     ///     match get_super_error() {
236     ///         Err(e) => {
237     ///             println!("Error: {e}");
238     ///             println!("Caused by: {}", e.source().unwrap());
239     ///         }
240     ///         _ => println!("No error"),
241     ///     }
242     /// }
243     /// ```
244     #[stable(feature = "error_source", since = "1.30.0")]
245     fn source(&self) -> Option<&(dyn Error + 'static)> {
246         None
247     }
248
249     /// Gets the `TypeId` of `self`.
250     #[doc(hidden)]
251     #[unstable(
252         feature = "error_type_id",
253         reason = "this is memory-unsafe to override in user code",
254         issue = "60784"
255     )]
256     fn type_id(&self, _: private::Internal) -> TypeId
257     where
258         Self: 'static,
259     {
260         TypeId::of::<Self>()
261     }
262
263     /// Returns a stack backtrace, if available, of where this error occurred.
264     ///
265     /// This function allows inspecting the location, in code, of where an error
266     /// happened. The returned `Backtrace` contains information about the stack
267     /// trace of the OS thread of execution of where the error originated from.
268     ///
269     /// Note that not all errors contain a `Backtrace`. Also note that a
270     /// `Backtrace` may actually be empty. For more information consult the
271     /// `Backtrace` type itself.
272     #[unstable(feature = "backtrace", issue = "53487")]
273     fn backtrace(&self) -> Option<&Backtrace> {
274         None
275     }
276
277     /// ```
278     /// if let Err(e) = "xc".parse::<u32>() {
279     ///     // Print `e` itself, no need for description().
280     ///     eprintln!("Error: {e}");
281     /// }
282     /// ```
283     #[stable(feature = "rust1", since = "1.0.0")]
284     #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
285     fn description(&self) -> &str {
286         "description() is deprecated; use Display"
287     }
288
289     #[stable(feature = "rust1", since = "1.0.0")]
290     #[deprecated(
291         since = "1.33.0",
292         note = "replaced by Error::source, which can support downcasting"
293     )]
294     #[allow(missing_docs)]
295     fn cause(&self) -> Option<&dyn Error> {
296         self.source()
297     }
298
299     /// Provides type based access to context intended for error reports.
300     ///
301     /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
302     /// references to member variables from `dyn Error` trait objects.
303     ///
304     /// # Example
305     ///
306     /// ```rust
307     /// #![feature(provide_any)]
308     /// #![feature(error_generic_member_access)]
309     /// use core::fmt;
310     /// use core::any::Demand;
311     ///
312     /// #[derive(Debug)]
313     /// struct MyBacktrace {
314     ///     // ...
315     /// }
316     ///
317     /// impl MyBacktrace {
318     ///     fn new() -> MyBacktrace {
319     ///         // ...
320     ///         # MyBacktrace {}
321     ///     }
322     /// }
323     ///
324     /// #[derive(Debug)]
325     /// struct SourceError {
326     ///     // ...
327     /// }
328     ///
329     /// impl fmt::Display for SourceError {
330     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331     ///         write!(f, "Example Source Error")
332     ///     }
333     /// }
334     ///
335     /// impl std::error::Error for SourceError {}
336     ///
337     /// #[derive(Debug)]
338     /// struct Error {
339     ///     source: SourceError,
340     ///     backtrace: MyBacktrace,
341     /// }
342     ///
343     /// impl fmt::Display for Error {
344     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
345     ///         write!(f, "Example Error")
346     ///     }
347     /// }
348     ///
349     /// impl std::error::Error for Error {
350     ///     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
351     ///         req
352     ///             .provide_ref::<MyBacktrace>(&self.backtrace)
353     ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
354     ///     }
355     /// }
356     ///
357     /// fn main() {
358     ///     let backtrace = MyBacktrace::new();
359     ///     let source = SourceError {};
360     ///     let error = Error { source, backtrace };
361     ///     let dyn_error = &error as &dyn std::error::Error;
362     ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
363     ///
364     ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
365     /// }
366     /// ```
367     #[unstable(feature = "error_generic_member_access", issue = "99301")]
368     #[allow(unused_variables)]
369     fn provide<'a>(&'a self, req: &mut Demand<'a>) {}
370 }
371
372 #[unstable(feature = "error_generic_member_access", issue = "99301")]
373 impl Provider for dyn Error + 'static {
374     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
375         self.provide(req)
376     }
377 }
378
379 mod private {
380     // This is a hack to prevent `type_id` from being overridden by `Error`
381     // implementations, since that can enable unsound downcasting.
382     #[unstable(feature = "error_type_id", issue = "60784")]
383     #[derive(Debug)]
384     pub struct Internal;
385 }
386
387 #[stable(feature = "rust1", since = "1.0.0")]
388 impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
389     /// Converts a type of [`Error`] into a box of dyn [`Error`].
390     ///
391     /// # Examples
392     ///
393     /// ```
394     /// use std::error::Error;
395     /// use std::fmt;
396     /// use std::mem;
397     ///
398     /// #[derive(Debug)]
399     /// struct AnError;
400     ///
401     /// impl fmt::Display for AnError {
402     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
403     ///         write!(f, "An error")
404     ///     }
405     /// }
406     ///
407     /// impl Error for AnError {}
408     ///
409     /// let an_error = AnError;
410     /// assert!(0 == mem::size_of_val(&an_error));
411     /// let a_boxed_error = Box::<dyn Error>::from(an_error);
412     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
413     /// ```
414     fn from(err: E) -> Box<dyn Error + 'a> {
415         Box::new(err)
416     }
417 }
418
419 #[stable(feature = "rust1", since = "1.0.0")]
420 impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
421     /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
422     /// dyn [`Error`] + [`Send`] + [`Sync`].
423     ///
424     /// # Examples
425     ///
426     /// ```
427     /// use std::error::Error;
428     /// use std::fmt;
429     /// use std::mem;
430     ///
431     /// #[derive(Debug)]
432     /// struct AnError;
433     ///
434     /// impl fmt::Display for AnError {
435     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436     ///         write!(f, "An error")
437     ///     }
438     /// }
439     ///
440     /// impl Error for AnError {}
441     ///
442     /// unsafe impl Send for AnError {}
443     ///
444     /// unsafe impl Sync for AnError {}
445     ///
446     /// let an_error = AnError;
447     /// assert!(0 == mem::size_of_val(&an_error));
448     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
449     /// assert!(
450     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
451     /// ```
452     fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
453         Box::new(err)
454     }
455 }
456
457 #[stable(feature = "rust1", since = "1.0.0")]
458 impl From<String> for Box<dyn Error + Send + Sync> {
459     /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
460     ///
461     /// # Examples
462     ///
463     /// ```
464     /// use std::error::Error;
465     /// use std::mem;
466     ///
467     /// let a_string_error = "a string error".to_string();
468     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
469     /// assert!(
470     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
471     /// ```
472     #[inline]
473     fn from(err: String) -> Box<dyn Error + Send + Sync> {
474         struct StringError(String);
475
476         impl Error for StringError {
477             #[allow(deprecated)]
478             fn description(&self) -> &str {
479                 &self.0
480             }
481         }
482
483         impl Display for StringError {
484             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
485                 Display::fmt(&self.0, f)
486             }
487         }
488
489         // Purposefully skip printing "StringError(..)"
490         impl Debug for StringError {
491             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
492                 Debug::fmt(&self.0, f)
493             }
494         }
495
496         Box::new(StringError(err))
497     }
498 }
499
500 #[stable(feature = "string_box_error", since = "1.6.0")]
501 impl From<String> for Box<dyn Error> {
502     /// Converts a [`String`] into a box of dyn [`Error`].
503     ///
504     /// # Examples
505     ///
506     /// ```
507     /// use std::error::Error;
508     /// use std::mem;
509     ///
510     /// let a_string_error = "a string error".to_string();
511     /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
512     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
513     /// ```
514     fn from(str_err: String) -> Box<dyn Error> {
515         let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
516         let err2: Box<dyn Error> = err1;
517         err2
518     }
519 }
520
521 #[stable(feature = "rust1", since = "1.0.0")]
522 impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
523     /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
524     ///
525     /// [`str`]: prim@str
526     ///
527     /// # Examples
528     ///
529     /// ```
530     /// use std::error::Error;
531     /// use std::mem;
532     ///
533     /// let a_str_error = "a str error";
534     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
535     /// assert!(
536     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
537     /// ```
538     #[inline]
539     fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
540         From::from(String::from(err))
541     }
542 }
543
544 #[stable(feature = "string_box_error", since = "1.6.0")]
545 impl From<&str> for Box<dyn Error> {
546     /// Converts a [`str`] into a box of dyn [`Error`].
547     ///
548     /// [`str`]: prim@str
549     ///
550     /// # Examples
551     ///
552     /// ```
553     /// use std::error::Error;
554     /// use std::mem;
555     ///
556     /// let a_str_error = "a str error";
557     /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
558     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
559     /// ```
560     fn from(err: &str) -> Box<dyn Error> {
561         From::from(String::from(err))
562     }
563 }
564
565 #[stable(feature = "cow_box_error", since = "1.22.0")]
566 impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
567     /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
568     ///
569     /// # Examples
570     ///
571     /// ```
572     /// use std::error::Error;
573     /// use std::mem;
574     /// use std::borrow::Cow;
575     ///
576     /// let a_cow_str_error = Cow::from("a str error");
577     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
578     /// assert!(
579     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
580     /// ```
581     fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
582         From::from(String::from(err))
583     }
584 }
585
586 #[stable(feature = "cow_box_error", since = "1.22.0")]
587 impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
588     /// Converts a [`Cow`] into a box of dyn [`Error`].
589     ///
590     /// # Examples
591     ///
592     /// ```
593     /// use std::error::Error;
594     /// use std::mem;
595     /// use std::borrow::Cow;
596     ///
597     /// let a_cow_str_error = Cow::from("a str error");
598     /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
599     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
600     /// ```
601     fn from(err: Cow<'a, str>) -> Box<dyn Error> {
602         From::from(String::from(err))
603     }
604 }
605
606 #[unstable(feature = "never_type", issue = "35121")]
607 impl Error for ! {}
608
609 #[unstable(
610     feature = "allocator_api",
611     reason = "the precise API and guarantees it provides may be tweaked.",
612     issue = "32838"
613 )]
614 impl Error for AllocError {}
615
616 #[stable(feature = "alloc_layout", since = "1.28.0")]
617 impl Error for LayoutError {}
618
619 #[stable(feature = "rust1", since = "1.0.0")]
620 impl Error for str::ParseBoolError {
621     #[allow(deprecated)]
622     fn description(&self) -> &str {
623         "failed to parse bool"
624     }
625 }
626
627 #[stable(feature = "rust1", since = "1.0.0")]
628 impl Error for str::Utf8Error {
629     #[allow(deprecated)]
630     fn description(&self) -> &str {
631         "invalid utf-8: corrupt contents"
632     }
633 }
634
635 #[stable(feature = "rust1", since = "1.0.0")]
636 impl Error for num::ParseIntError {
637     #[allow(deprecated)]
638     fn description(&self) -> &str {
639         self.__description()
640     }
641 }
642
643 #[stable(feature = "try_from", since = "1.34.0")]
644 impl Error for num::TryFromIntError {
645     #[allow(deprecated)]
646     fn description(&self) -> &str {
647         self.__description()
648     }
649 }
650
651 #[stable(feature = "try_from", since = "1.34.0")]
652 impl Error for array::TryFromSliceError {
653     #[allow(deprecated)]
654     fn description(&self) -> &str {
655         self.__description()
656     }
657 }
658
659 #[stable(feature = "rust1", since = "1.0.0")]
660 impl Error for num::ParseFloatError {
661     #[allow(deprecated)]
662     fn description(&self) -> &str {
663         self.__description()
664     }
665 }
666
667 #[stable(feature = "rust1", since = "1.0.0")]
668 impl Error for string::FromUtf8Error {
669     #[allow(deprecated)]
670     fn description(&self) -> &str {
671         "invalid utf-8"
672     }
673 }
674
675 #[stable(feature = "rust1", since = "1.0.0")]
676 impl Error for string::FromUtf16Error {
677     #[allow(deprecated)]
678     fn description(&self) -> &str {
679         "invalid utf-16"
680     }
681 }
682
683 #[stable(feature = "str_parse_error2", since = "1.8.0")]
684 impl Error for Infallible {
685     fn description(&self) -> &str {
686         match *self {}
687     }
688 }
689
690 #[stable(feature = "decode_utf16", since = "1.9.0")]
691 impl Error for char::DecodeUtf16Error {
692     #[allow(deprecated)]
693     fn description(&self) -> &str {
694         "unpaired surrogate found"
695     }
696 }
697
698 #[stable(feature = "u8_from_char", since = "1.59.0")]
699 impl Error for char::TryFromCharError {}
700
701 #[unstable(feature = "map_try_insert", issue = "82766")]
702 impl<'a, K: Debug + Ord, V: Debug> Error
703     for crate::collections::btree_map::OccupiedError<'a, K, V>
704 {
705     #[allow(deprecated)]
706     fn description(&self) -> &str {
707         "key already exists"
708     }
709 }
710
711 #[unstable(feature = "map_try_insert", issue = "82766")]
712 impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> {
713     #[allow(deprecated)]
714     fn description(&self) -> &str {
715         "key already exists"
716     }
717 }
718
719 #[stable(feature = "box_error", since = "1.8.0")]
720 impl<T: Error> Error for Box<T> {
721     #[allow(deprecated, deprecated_in_future)]
722     fn description(&self) -> &str {
723         Error::description(&**self)
724     }
725
726     #[allow(deprecated)]
727     fn cause(&self) -> Option<&dyn Error> {
728         Error::cause(&**self)
729     }
730
731     fn source(&self) -> Option<&(dyn Error + 'static)> {
732         Error::source(&**self)
733     }
734 }
735
736 #[unstable(feature = "thin_box", issue = "92791")]
737 impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::ThinBox<T> {
738     fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> {
739         use core::ops::Deref;
740         self.deref().source()
741     }
742 }
743
744 #[stable(feature = "error_by_ref", since = "1.51.0")]
745 impl<'a, T: Error + ?Sized> Error for &'a T {
746     #[allow(deprecated, deprecated_in_future)]
747     fn description(&self) -> &str {
748         Error::description(&**self)
749     }
750
751     #[allow(deprecated)]
752     fn cause(&self) -> Option<&dyn Error> {
753         Error::cause(&**self)
754     }
755
756     fn source(&self) -> Option<&(dyn Error + 'static)> {
757         Error::source(&**self)
758     }
759
760     fn backtrace(&self) -> Option<&Backtrace> {
761         Error::backtrace(&**self)
762     }
763 }
764
765 #[stable(feature = "arc_error", since = "1.52.0")]
766 impl<T: Error + ?Sized> Error for Arc<T> {
767     #[allow(deprecated, deprecated_in_future)]
768     fn description(&self) -> &str {
769         Error::description(&**self)
770     }
771
772     #[allow(deprecated)]
773     fn cause(&self) -> Option<&dyn Error> {
774         Error::cause(&**self)
775     }
776
777     fn source(&self) -> Option<&(dyn Error + 'static)> {
778         Error::source(&**self)
779     }
780
781     fn backtrace(&self) -> Option<&Backtrace> {
782         Error::backtrace(&**self)
783     }
784 }
785
786 #[stable(feature = "fmt_error", since = "1.11.0")]
787 impl Error for fmt::Error {
788     #[allow(deprecated)]
789     fn description(&self) -> &str {
790         "an error occurred when formatting an argument"
791     }
792 }
793
794 #[stable(feature = "try_borrow", since = "1.13.0")]
795 impl Error for cell::BorrowError {
796     #[allow(deprecated)]
797     fn description(&self) -> &str {
798         "already mutably borrowed"
799     }
800 }
801
802 #[stable(feature = "try_borrow", since = "1.13.0")]
803 impl Error for cell::BorrowMutError {
804     #[allow(deprecated)]
805     fn description(&self) -> &str {
806         "already borrowed"
807     }
808 }
809
810 #[stable(feature = "try_from", since = "1.34.0")]
811 impl Error for char::CharTryFromError {
812     #[allow(deprecated)]
813     fn description(&self) -> &str {
814         "converted integer out of range for `char`"
815     }
816 }
817
818 #[stable(feature = "char_from_str", since = "1.20.0")]
819 impl Error for char::ParseCharError {
820     #[allow(deprecated)]
821     fn description(&self) -> &str {
822         self.__description()
823     }
824 }
825
826 #[stable(feature = "try_reserve", since = "1.57.0")]
827 impl Error for alloc::collections::TryReserveError {}
828
829 #[unstable(feature = "duration_checked_float", issue = "83400")]
830 impl Error for time::FromFloatSecsError {}
831
832 #[stable(feature = "rust1", since = "1.0.0")]
833 impl Error for alloc::ffi::NulError {
834     #[allow(deprecated)]
835     fn description(&self) -> &str {
836         "nul byte found in data"
837     }
838 }
839
840 #[stable(feature = "rust1", since = "1.0.0")]
841 impl From<alloc::ffi::NulError> for io::Error {
842     /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`].
843     fn from(_: alloc::ffi::NulError) -> io::Error {
844         io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
845     }
846 }
847
848 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
849 impl Error for core::ffi::FromBytesWithNulError {
850     #[allow(deprecated)]
851     fn description(&self) -> &str {
852         self.__description()
853     }
854 }
855
856 #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
857 impl Error for core::ffi::FromBytesUntilNulError {}
858
859 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
860 impl Error for alloc::ffi::FromVecWithNulError {}
861
862 #[stable(feature = "cstring_into", since = "1.7.0")]
863 impl Error for alloc::ffi::IntoStringError {
864     #[allow(deprecated)]
865     fn description(&self) -> &str {
866         "C string contained non-utf8 bytes"
867     }
868
869     fn source(&self) -> Option<&(dyn Error + 'static)> {
870         Some(self.__source())
871     }
872 }
873
874 // Copied from `any.rs`.
875 impl dyn Error + 'static {
876     /// Returns `true` if the inner type is the same as `T`.
877     #[stable(feature = "error_downcast", since = "1.3.0")]
878     #[inline]
879     pub fn is<T: Error + 'static>(&self) -> bool {
880         // Get `TypeId` of the type this function is instantiated with.
881         let t = TypeId::of::<T>();
882
883         // Get `TypeId` of the type in the trait object (`self`).
884         let concrete = self.type_id(private::Internal);
885
886         // Compare both `TypeId`s on equality.
887         t == concrete
888     }
889
890     /// Returns some reference to the inner value if it is of type `T`, or
891     /// `None` if it isn't.
892     #[stable(feature = "error_downcast", since = "1.3.0")]
893     #[inline]
894     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
895         if self.is::<T>() {
896             unsafe { Some(&*(self as *const dyn Error as *const T)) }
897         } else {
898             None
899         }
900     }
901
902     /// Returns some mutable reference to the inner value if it is of type `T`, or
903     /// `None` if it isn't.
904     #[stable(feature = "error_downcast", since = "1.3.0")]
905     #[inline]
906     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
907         if self.is::<T>() {
908             unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
909         } else {
910             None
911         }
912     }
913
914     /// Request a reference of type `T` as context about this error.
915     #[unstable(feature = "error_generic_member_access", issue = "99301")]
916     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
917         core::any::request_ref(self)
918     }
919
920     /// Request a value of type `T` as context about this error.
921     #[unstable(feature = "error_generic_member_access", issue = "99301")]
922     pub fn request_value<T: 'static>(&self) -> Option<T> {
923         core::any::request_value(self)
924     }
925 }
926
927 impl dyn Error + 'static + Send {
928     /// Forwards to the method defined on the type `dyn Error`.
929     #[stable(feature = "error_downcast", since = "1.3.0")]
930     #[inline]
931     pub fn is<T: Error + 'static>(&self) -> bool {
932         <dyn Error + 'static>::is::<T>(self)
933     }
934
935     /// Forwards to the method defined on the type `dyn Error`.
936     #[stable(feature = "error_downcast", since = "1.3.0")]
937     #[inline]
938     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
939         <dyn Error + 'static>::downcast_ref::<T>(self)
940     }
941
942     /// Forwards to the method defined on the type `dyn Error`.
943     #[stable(feature = "error_downcast", since = "1.3.0")]
944     #[inline]
945     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
946         <dyn Error + 'static>::downcast_mut::<T>(self)
947     }
948
949     /// Request a reference of type `T` as context about this error.
950     #[unstable(feature = "error_generic_member_access", issue = "99301")]
951     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
952         <dyn Error + 'static>::request_ref(self)
953     }
954
955     /// Request a value of type `T` as context about this error.
956     #[unstable(feature = "error_generic_member_access", issue = "99301")]
957     pub fn request_value<T: 'static>(&self) -> Option<T> {
958         <dyn Error + 'static>::request_value(self)
959     }
960 }
961
962 impl dyn Error + 'static + Send + Sync {
963     /// Forwards to the method defined on the type `dyn Error`.
964     #[stable(feature = "error_downcast", since = "1.3.0")]
965     #[inline]
966     pub fn is<T: Error + 'static>(&self) -> bool {
967         <dyn Error + 'static>::is::<T>(self)
968     }
969
970     /// Forwards to the method defined on the type `dyn Error`.
971     #[stable(feature = "error_downcast", since = "1.3.0")]
972     #[inline]
973     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
974         <dyn Error + 'static>::downcast_ref::<T>(self)
975     }
976
977     /// Forwards to the method defined on the type `dyn Error`.
978     #[stable(feature = "error_downcast", since = "1.3.0")]
979     #[inline]
980     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
981         <dyn Error + 'static>::downcast_mut::<T>(self)
982     }
983
984     /// Request a reference of type `T` as context about this error.
985     #[unstable(feature = "error_generic_member_access", issue = "99301")]
986     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
987         <dyn Error + 'static>::request_ref(self)
988     }
989
990     /// Request a value of type `T` as context about this error.
991     #[unstable(feature = "error_generic_member_access", issue = "99301")]
992     pub fn request_value<T: 'static>(&self) -> Option<T> {
993         <dyn Error + 'static>::request_value(self)
994     }
995 }
996
997 impl dyn Error {
998     #[inline]
999     #[stable(feature = "error_downcast", since = "1.3.0")]
1000     /// Attempts to downcast the box to a concrete type.
1001     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
1002         if self.is::<T>() {
1003             unsafe {
1004                 let raw: *mut dyn Error = Box::into_raw(self);
1005                 Ok(Box::from_raw(raw as *mut T))
1006             }
1007         } else {
1008             Err(self)
1009         }
1010     }
1011
1012     /// Returns an iterator starting with the current error and continuing with
1013     /// recursively calling [`Error::source`].
1014     ///
1015     /// If you want to omit the current error and only use its sources,
1016     /// use `skip(1)`.
1017     ///
1018     /// # Examples
1019     ///
1020     /// ```
1021     /// #![feature(error_iter)]
1022     /// use std::error::Error;
1023     /// use std::fmt;
1024     ///
1025     /// #[derive(Debug)]
1026     /// struct A;
1027     ///
1028     /// #[derive(Debug)]
1029     /// struct B(Option<Box<dyn Error + 'static>>);
1030     ///
1031     /// impl fmt::Display for A {
1032     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1033     ///         write!(f, "A")
1034     ///     }
1035     /// }
1036     ///
1037     /// impl fmt::Display for B {
1038     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1039     ///         write!(f, "B")
1040     ///     }
1041     /// }
1042     ///
1043     /// impl Error for A {}
1044     ///
1045     /// impl Error for B {
1046     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
1047     ///         self.0.as_ref().map(|e| e.as_ref())
1048     ///     }
1049     /// }
1050     ///
1051     /// let b = B(Some(Box::new(A)));
1052     ///
1053     /// // let err : Box<Error> = b.into(); // or
1054     /// let err = &b as &(dyn Error);
1055     ///
1056     /// let mut iter = err.chain();
1057     ///
1058     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
1059     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
1060     /// assert!(iter.next().is_none());
1061     /// assert!(iter.next().is_none());
1062     /// ```
1063     #[unstable(feature = "error_iter", issue = "58520")]
1064     #[inline]
1065     pub fn chain(&self) -> Chain<'_> {
1066         Chain { current: Some(self) }
1067     }
1068 }
1069
1070 /// An iterator over an [`Error`] and its sources.
1071 ///
1072 /// If you want to omit the initial error and only process
1073 /// its sources, use `skip(1)`.
1074 #[unstable(feature = "error_iter", issue = "58520")]
1075 #[derive(Clone, Debug)]
1076 pub struct Chain<'a> {
1077     current: Option<&'a (dyn Error + 'static)>,
1078 }
1079
1080 #[unstable(feature = "error_iter", issue = "58520")]
1081 impl<'a> Iterator for Chain<'a> {
1082     type Item = &'a (dyn Error + 'static);
1083
1084     fn next(&mut self) -> Option<Self::Item> {
1085         let current = self.current;
1086         self.current = self.current.and_then(Error::source);
1087         current
1088     }
1089 }
1090
1091 impl dyn Error + Send {
1092     #[inline]
1093     #[stable(feature = "error_downcast", since = "1.3.0")]
1094     /// Attempts to downcast the box to a concrete type.
1095     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
1096         let err: Box<dyn Error> = self;
1097         <dyn Error>::downcast(err).map_err(|s| unsafe {
1098             // Reapply the `Send` marker.
1099             transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
1100         })
1101     }
1102 }
1103
1104 impl dyn Error + Send + Sync {
1105     #[inline]
1106     #[stable(feature = "error_downcast", since = "1.3.0")]
1107     /// Attempts to downcast the box to a concrete type.
1108     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
1109         let err: Box<dyn Error> = self;
1110         <dyn Error>::downcast(err).map_err(|s| unsafe {
1111             // Reapply the `Send + Sync` marker.
1112             transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
1113         })
1114     }
1115 }
1116
1117 /// An error reporter that prints an error and its sources.
1118 ///
1119 /// Report also exposes configuration options for formatting the error chain, either entirely on a
1120 /// single line, or in multi-line format with each cause in the error chain on a new line.
1121 ///
1122 /// `Report` only requires that the wrapped error implement `Error`. It doesn't require that the
1123 /// wrapped error be `Send`, `Sync`, or `'static`.
1124 ///
1125 /// # Examples
1126 ///
1127 /// ```rust
1128 /// #![feature(error_reporter)]
1129 /// use std::error::{Error, Report};
1130 /// use std::fmt;
1131 ///
1132 /// #[derive(Debug)]
1133 /// struct SuperError {
1134 ///     source: SuperErrorSideKick,
1135 /// }
1136 ///
1137 /// impl fmt::Display for SuperError {
1138 ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1139 ///         write!(f, "SuperError is here!")
1140 ///     }
1141 /// }
1142 ///
1143 /// impl Error for SuperError {
1144 ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
1145 ///         Some(&self.source)
1146 ///     }
1147 /// }
1148 ///
1149 /// #[derive(Debug)]
1150 /// struct SuperErrorSideKick;
1151 ///
1152 /// impl fmt::Display for SuperErrorSideKick {
1153 ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1154 ///         write!(f, "SuperErrorSideKick is here!")
1155 ///     }
1156 /// }
1157 ///
1158 /// impl Error for SuperErrorSideKick {}
1159 ///
1160 /// fn get_super_error() -> Result<(), SuperError> {
1161 ///     Err(SuperError { source: SuperErrorSideKick })
1162 /// }
1163 ///
1164 /// fn main() {
1165 ///     match get_super_error() {
1166 ///         Err(e) => println!("Error: {}", Report::new(e)),
1167 ///         _ => println!("No error"),
1168 ///     }
1169 /// }
1170 /// ```
1171 ///
1172 /// This example produces the following output:
1173 ///
1174 /// ```console
1175 /// Error: SuperError is here!: SuperErrorSideKick is here!
1176 /// ```
1177 ///
1178 /// ## Output consistency
1179 ///
1180 /// Report prints the same output via `Display` and `Debug`, so it works well with
1181 /// [`Result::unwrap`]/[`Result::expect`] which print their `Err` variant via `Debug`:
1182 ///
1183 /// ```should_panic
1184 /// #![feature(error_reporter)]
1185 /// use std::error::Report;
1186 /// # use std::error::Error;
1187 /// # use std::fmt;
1188 /// # #[derive(Debug)]
1189 /// # struct SuperError {
1190 /// #     source: SuperErrorSideKick,
1191 /// # }
1192 /// # impl fmt::Display for SuperError {
1193 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1194 /// #         write!(f, "SuperError is here!")
1195 /// #     }
1196 /// # }
1197 /// # impl Error for SuperError {
1198 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1199 /// #         Some(&self.source)
1200 /// #     }
1201 /// # }
1202 /// # #[derive(Debug)]
1203 /// # struct SuperErrorSideKick;
1204 /// # impl fmt::Display for SuperErrorSideKick {
1205 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1206 /// #         write!(f, "SuperErrorSideKick is here!")
1207 /// #     }
1208 /// # }
1209 /// # impl Error for SuperErrorSideKick {}
1210 /// # fn get_super_error() -> Result<(), SuperError> {
1211 /// #     Err(SuperError { source: SuperErrorSideKick })
1212 /// # }
1213 ///
1214 /// get_super_error().map_err(Report::new).unwrap();
1215 /// ```
1216 ///
1217 /// This example produces the following output:
1218 ///
1219 /// ```console
1220 /// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
1221 /// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1222 /// ```
1223 ///
1224 /// ## Return from `main`
1225 ///
1226 /// `Report` also implements `From` for all types that implement [`Error`]; this when combined with
1227 /// the `Debug` output means `Report` is an ideal starting place for formatting errors returned
1228 /// from `main`.
1229 ///
1230 /// ```should_panic
1231 /// #![feature(error_reporter)]
1232 /// use std::error::Report;
1233 /// # use std::error::Error;
1234 /// # use std::fmt;
1235 /// # #[derive(Debug)]
1236 /// # struct SuperError {
1237 /// #     source: SuperErrorSideKick,
1238 /// # }
1239 /// # impl fmt::Display for SuperError {
1240 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1241 /// #         write!(f, "SuperError is here!")
1242 /// #     }
1243 /// # }
1244 /// # impl Error for SuperError {
1245 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1246 /// #         Some(&self.source)
1247 /// #     }
1248 /// # }
1249 /// # #[derive(Debug)]
1250 /// # struct SuperErrorSideKick;
1251 /// # impl fmt::Display for SuperErrorSideKick {
1252 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1253 /// #         write!(f, "SuperErrorSideKick is here!")
1254 /// #     }
1255 /// # }
1256 /// # impl Error for SuperErrorSideKick {}
1257 /// # fn get_super_error() -> Result<(), SuperError> {
1258 /// #     Err(SuperError { source: SuperErrorSideKick })
1259 /// # }
1260 ///
1261 /// fn main() -> Result<(), Report> {
1262 ///     get_super_error()?;
1263 ///     Ok(())
1264 /// }
1265 /// ```
1266 ///
1267 /// This example produces the following output:
1268 ///
1269 /// ```console
1270 /// Error: SuperError is here!: SuperErrorSideKick is here!
1271 /// ```
1272 ///
1273 /// **Note**: `Report`s constructed via `?` and `From` will be configured to use the single line
1274 /// output format. If you want to make sure your `Report`s are pretty printed and include backtrace
1275 /// you will need to manually convert and enable those flags.
1276 ///
1277 /// ```should_panic
1278 /// #![feature(error_reporter)]
1279 /// use std::error::Report;
1280 /// # use std::error::Error;
1281 /// # use std::fmt;
1282 /// # #[derive(Debug)]
1283 /// # struct SuperError {
1284 /// #     source: SuperErrorSideKick,
1285 /// # }
1286 /// # impl fmt::Display for SuperError {
1287 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1288 /// #         write!(f, "SuperError is here!")
1289 /// #     }
1290 /// # }
1291 /// # impl Error for SuperError {
1292 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1293 /// #         Some(&self.source)
1294 /// #     }
1295 /// # }
1296 /// # #[derive(Debug)]
1297 /// # struct SuperErrorSideKick;
1298 /// # impl fmt::Display for SuperErrorSideKick {
1299 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300 /// #         write!(f, "SuperErrorSideKick is here!")
1301 /// #     }
1302 /// # }
1303 /// # impl Error for SuperErrorSideKick {}
1304 /// # fn get_super_error() -> Result<(), SuperError> {
1305 /// #     Err(SuperError { source: SuperErrorSideKick })
1306 /// # }
1307 ///
1308 /// fn main() -> Result<(), Report> {
1309 ///     get_super_error()
1310 ///         .map_err(Report::from)
1311 ///         .map_err(|r| r.pretty(true).show_backtrace(true))?;
1312 ///     Ok(())
1313 /// }
1314 /// ```
1315 ///
1316 /// This example produces the following output:
1317 ///
1318 /// ```console
1319 /// Error: SuperError is here!
1320 ///
1321 /// Caused by:
1322 ///       SuperErrorSideKick is here!
1323 /// ```
1324 #[unstable(feature = "error_reporter", issue = "90172")]
1325 pub struct Report<E = Box<dyn Error>> {
1326     /// The error being reported.
1327     error: E,
1328     /// Whether a backtrace should be included as part of the report.
1329     show_backtrace: bool,
1330     /// Whether the report should be pretty-printed.
1331     pretty: bool,
1332 }
1333
1334 impl<E> Report<E>
1335 where
1336     Report<E>: From<E>,
1337 {
1338     /// Create a new `Report` from an input error.
1339     #[unstable(feature = "error_reporter", issue = "90172")]
1340     pub fn new(error: E) -> Report<E> {
1341         Self::from(error)
1342     }
1343 }
1344
1345 impl<E> Report<E> {
1346     /// Enable pretty-printing the report across multiple lines.
1347     ///
1348     /// # Examples
1349     ///
1350     /// ```rust
1351     /// #![feature(error_reporter)]
1352     /// use std::error::Report;
1353     /// # use std::error::Error;
1354     /// # use std::fmt;
1355     /// # #[derive(Debug)]
1356     /// # struct SuperError {
1357     /// #     source: SuperErrorSideKick,
1358     /// # }
1359     /// # impl fmt::Display for SuperError {
1360     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1361     /// #         write!(f, "SuperError is here!")
1362     /// #     }
1363     /// # }
1364     /// # impl Error for SuperError {
1365     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1366     /// #         Some(&self.source)
1367     /// #     }
1368     /// # }
1369     /// # #[derive(Debug)]
1370     /// # struct SuperErrorSideKick;
1371     /// # impl fmt::Display for SuperErrorSideKick {
1372     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1373     /// #         write!(f, "SuperErrorSideKick is here!")
1374     /// #     }
1375     /// # }
1376     /// # impl Error for SuperErrorSideKick {}
1377     ///
1378     /// let error = SuperError { source: SuperErrorSideKick };
1379     /// let report = Report::new(error).pretty(true);
1380     /// eprintln!("Error: {report:?}");
1381     /// ```
1382     ///
1383     /// This example produces the following output:
1384     ///
1385     /// ```console
1386     /// Error: SuperError is here!
1387     ///
1388     /// Caused by:
1389     ///       SuperErrorSideKick is here!
1390     /// ```
1391     ///
1392     /// When there are multiple source errors the causes will be numbered in order of iteration
1393     /// starting from the outermost error.
1394     ///
1395     /// ```rust
1396     /// #![feature(error_reporter)]
1397     /// use std::error::Report;
1398     /// # use std::error::Error;
1399     /// # use std::fmt;
1400     /// # #[derive(Debug)]
1401     /// # struct SuperError {
1402     /// #     source: SuperErrorSideKick,
1403     /// # }
1404     /// # impl fmt::Display for SuperError {
1405     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1406     /// #         write!(f, "SuperError is here!")
1407     /// #     }
1408     /// # }
1409     /// # impl Error for SuperError {
1410     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1411     /// #         Some(&self.source)
1412     /// #     }
1413     /// # }
1414     /// # #[derive(Debug)]
1415     /// # struct SuperErrorSideKick {
1416     /// #     source: SuperErrorSideKickSideKick,
1417     /// # }
1418     /// # impl fmt::Display for SuperErrorSideKick {
1419     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1420     /// #         write!(f, "SuperErrorSideKick is here!")
1421     /// #     }
1422     /// # }
1423     /// # impl Error for SuperErrorSideKick {
1424     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1425     /// #         Some(&self.source)
1426     /// #     }
1427     /// # }
1428     /// # #[derive(Debug)]
1429     /// # struct SuperErrorSideKickSideKick;
1430     /// # impl fmt::Display for SuperErrorSideKickSideKick {
1431     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1432     /// #         write!(f, "SuperErrorSideKickSideKick is here!")
1433     /// #     }
1434     /// # }
1435     /// # impl Error for SuperErrorSideKickSideKick { }
1436     ///
1437     /// let source = SuperErrorSideKickSideKick;
1438     /// let source = SuperErrorSideKick { source };
1439     /// let error = SuperError { source };
1440     /// let report = Report::new(error).pretty(true);
1441     /// eprintln!("Error: {report:?}");
1442     /// ```
1443     ///
1444     /// This example produces the following output:
1445     ///
1446     /// ```console
1447     /// Error: SuperError is here!
1448     ///
1449     /// Caused by:
1450     ///    0: SuperErrorSideKick is here!
1451     ///    1: SuperErrorSideKickSideKick is here!
1452     /// ```
1453     #[unstable(feature = "error_reporter", issue = "90172")]
1454     pub fn pretty(mut self, pretty: bool) -> Self {
1455         self.pretty = pretty;
1456         self
1457     }
1458
1459     /// Display backtrace if available when using pretty output format.
1460     ///
1461     /// # Examples
1462     ///
1463     /// **Note**: Report will search for the first `Backtrace` it can find starting from the
1464     /// outermost error. In this example it will display the backtrace from the second error in the
1465     /// chain, `SuperErrorSideKick`.
1466     ///
1467     /// ```rust
1468     /// #![feature(error_reporter)]
1469     /// #![feature(backtrace)]
1470     /// # use std::error::Error;
1471     /// # use std::fmt;
1472     /// use std::error::Report;
1473     /// use std::backtrace::Backtrace;
1474     ///
1475     /// # #[derive(Debug)]
1476     /// # struct SuperError {
1477     /// #     source: SuperErrorSideKick,
1478     /// # }
1479     /// # impl fmt::Display for SuperError {
1480     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1481     /// #         write!(f, "SuperError is here!")
1482     /// #     }
1483     /// # }
1484     /// # impl Error for SuperError {
1485     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1486     /// #         Some(&self.source)
1487     /// #     }
1488     /// # }
1489     /// #[derive(Debug)]
1490     /// struct SuperErrorSideKick {
1491     ///     backtrace: Backtrace,
1492     /// }
1493     ///
1494     /// impl SuperErrorSideKick {
1495     ///     fn new() -> SuperErrorSideKick {
1496     ///         SuperErrorSideKick { backtrace: Backtrace::force_capture() }
1497     ///     }
1498     /// }
1499     ///
1500     /// impl Error for SuperErrorSideKick {
1501     ///     fn backtrace(&self) -> Option<&Backtrace> {
1502     ///         Some(&self.backtrace)
1503     ///     }
1504     /// }
1505     ///
1506     /// // The rest of the example is unchanged ...
1507     /// # impl fmt::Display for SuperErrorSideKick {
1508     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1509     /// #         write!(f, "SuperErrorSideKick is here!")
1510     /// #     }
1511     /// # }
1512     ///
1513     /// let source = SuperErrorSideKick::new();
1514     /// let error = SuperError { source };
1515     /// let report = Report::new(error).pretty(true).show_backtrace(true);
1516     /// eprintln!("Error: {report:?}");
1517     /// ```
1518     ///
1519     /// This example produces something similar to the following output:
1520     ///
1521     /// ```console
1522     /// Error: SuperError is here!
1523     ///
1524     /// Caused by:
1525     ///       SuperErrorSideKick is here!
1526     ///
1527     /// Stack backtrace:
1528     ///    0: rust_out::main::_doctest_main_src_error_rs_1158_0::SuperErrorSideKick::new
1529     ///    1: rust_out::main::_doctest_main_src_error_rs_1158_0
1530     ///    2: rust_out::main
1531     ///    3: core::ops::function::FnOnce::call_once
1532     ///    4: std::sys_common::backtrace::__rust_begin_short_backtrace
1533     ///    5: std::rt::lang_start::{{closure}}
1534     ///    6: std::panicking::try
1535     ///    7: std::rt::lang_start_internal
1536     ///    8: std::rt::lang_start
1537     ///    9: main
1538     ///   10: __libc_start_main
1539     ///   11: _start
1540     /// ```
1541     #[unstable(feature = "error_reporter", issue = "90172")]
1542     pub fn show_backtrace(mut self, show_backtrace: bool) -> Self {
1543         self.show_backtrace = show_backtrace;
1544         self
1545     }
1546 }
1547
1548 impl<E> Report<E>
1549 where
1550     E: Error,
1551 {
1552     fn backtrace(&self) -> Option<&Backtrace> {
1553         // have to grab the backtrace on the first error directly since that error may not be
1554         // 'static
1555         let backtrace = self.error.backtrace();
1556         let backtrace = backtrace.or_else(|| {
1557             self.error
1558                 .source()
1559                 .map(|source| source.chain().find_map(|source| source.backtrace()))
1560                 .flatten()
1561         });
1562         backtrace
1563     }
1564
1565     /// Format the report as a single line.
1566     #[unstable(feature = "error_reporter", issue = "90172")]
1567     fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1568         write!(f, "{}", self.error)?;
1569
1570         let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
1571
1572         for cause in sources {
1573             write!(f, ": {cause}")?;
1574         }
1575
1576         Ok(())
1577     }
1578
1579     /// Format the report as multiple lines, with each error cause on its own line.
1580     #[unstable(feature = "error_reporter", issue = "90172")]
1581     fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1582         let error = &self.error;
1583
1584         write!(f, "{error}")?;
1585
1586         if let Some(cause) = error.source() {
1587             write!(f, "\n\nCaused by:")?;
1588
1589             let multiple = cause.source().is_some();
1590
1591             for (ind, error) in cause.chain().enumerate() {
1592                 writeln!(f)?;
1593                 let mut indented = Indented { inner: f };
1594                 if multiple {
1595                     write!(indented, "{ind: >4}: {error}")?;
1596                 } else {
1597                     write!(indented, "      {error}")?;
1598                 }
1599             }
1600         }
1601
1602         if self.show_backtrace {
1603             let backtrace = self.backtrace();
1604
1605             if let Some(backtrace) = backtrace {
1606                 let backtrace = backtrace.to_string();
1607
1608                 f.write_str("\n\nStack backtrace:\n")?;
1609                 f.write_str(backtrace.trim_end())?;
1610             }
1611         }
1612
1613         Ok(())
1614     }
1615 }
1616
1617 impl Report<Box<dyn Error>> {
1618     fn backtrace(&self) -> Option<&Backtrace> {
1619         // have to grab the backtrace on the first error directly since that error may not be
1620         // 'static
1621         let backtrace = self.error.backtrace();
1622         let backtrace = backtrace.or_else(|| {
1623             self.error
1624                 .source()
1625                 .map(|source| source.chain().find_map(|source| source.backtrace()))
1626                 .flatten()
1627         });
1628         backtrace
1629     }
1630
1631     /// Format the report as a single line.
1632     #[unstable(feature = "error_reporter", issue = "90172")]
1633     fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1634         write!(f, "{}", self.error)?;
1635
1636         let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
1637
1638         for cause in sources {
1639             write!(f, ": {cause}")?;
1640         }
1641
1642         Ok(())
1643     }
1644
1645     /// Format the report as multiple lines, with each error cause on its own line.
1646     #[unstable(feature = "error_reporter", issue = "90172")]
1647     fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1648         let error = &self.error;
1649
1650         write!(f, "{error}")?;
1651
1652         if let Some(cause) = error.source() {
1653             write!(f, "\n\nCaused by:")?;
1654
1655             let multiple = cause.source().is_some();
1656
1657             for (ind, error) in cause.chain().enumerate() {
1658                 writeln!(f)?;
1659                 let mut indented = Indented { inner: f };
1660                 if multiple {
1661                     write!(indented, "{ind: >4}: {error}")?;
1662                 } else {
1663                     write!(indented, "      {error}")?;
1664                 }
1665             }
1666         }
1667
1668         if self.show_backtrace {
1669             let backtrace = self.backtrace();
1670
1671             if let Some(backtrace) = backtrace {
1672                 let backtrace = backtrace.to_string();
1673
1674                 f.write_str("\n\nStack backtrace:\n")?;
1675                 f.write_str(backtrace.trim_end())?;
1676             }
1677         }
1678
1679         Ok(())
1680     }
1681 }
1682
1683 #[unstable(feature = "error_reporter", issue = "90172")]
1684 impl<E> From<E> for Report<E>
1685 where
1686     E: Error,
1687 {
1688     fn from(error: E) -> Self {
1689         Report { error, show_backtrace: false, pretty: false }
1690     }
1691 }
1692
1693 #[unstable(feature = "error_reporter", issue = "90172")]
1694 impl<'a, E> From<E> for Report<Box<dyn Error + 'a>>
1695 where
1696     E: Error + 'a,
1697 {
1698     fn from(error: E) -> Self {
1699         let error = box error;
1700         Report { error, show_backtrace: false, pretty: false }
1701     }
1702 }
1703
1704 #[unstable(feature = "error_reporter", issue = "90172")]
1705 impl<E> fmt::Display for Report<E>
1706 where
1707     E: Error,
1708 {
1709     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1710         if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
1711     }
1712 }
1713
1714 #[unstable(feature = "error_reporter", issue = "90172")]
1715 impl fmt::Display for Report<Box<dyn Error>> {
1716     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1717         if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
1718     }
1719 }
1720
1721 // This type intentionally outputs the same format for `Display` and `Debug`for
1722 // situations where you unwrap a `Report` or return it from main.
1723 #[unstable(feature = "error_reporter", issue = "90172")]
1724 impl<E> fmt::Debug for Report<E>
1725 where
1726     Report<E>: fmt::Display,
1727 {
1728     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1729         fmt::Display::fmt(self, f)
1730     }
1731 }
1732
1733 /// Wrapper type for indenting the inner source.
1734 struct Indented<'a, D> {
1735     inner: &'a mut D,
1736 }
1737
1738 impl<T> Write for Indented<'_, T>
1739 where
1740     T: Write,
1741 {
1742     fn write_str(&mut self, s: &str) -> fmt::Result {
1743         for (i, line) in s.split('\n').enumerate() {
1744             if i > 0 {
1745                 self.inner.write_char('\n')?;
1746                 self.inner.write_str("      ")?;
1747             }
1748
1749             self.inner.write_str(line)?;
1750         }
1751
1752         Ok(())
1753     }
1754 }