]> git.lizzy.rs Git - rust.git/blob - library/std/src/error.rs
Rollup merge of #100861 - RalfJung:const-ice, r=oli-obk
[rust.git] / library / std / src / error.rs
1 //! The `Error` trait provides common functionality for 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     /// ```
264     /// if let Err(e) = "xc".parse::<u32>() {
265     ///     // Print `e` itself, no need for description().
266     ///     eprintln!("Error: {e}");
267     /// }
268     /// ```
269     #[stable(feature = "rust1", since = "1.0.0")]
270     #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
271     fn description(&self) -> &str {
272         "description() is deprecated; use Display"
273     }
274
275     #[stable(feature = "rust1", since = "1.0.0")]
276     #[deprecated(
277         since = "1.33.0",
278         note = "replaced by Error::source, which can support downcasting"
279     )]
280     #[allow(missing_docs)]
281     fn cause(&self) -> Option<&dyn Error> {
282         self.source()
283     }
284
285     /// Provides type based access to context intended for error reports.
286     ///
287     /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
288     /// references to member variables from `dyn Error` trait objects.
289     ///
290     /// # Example
291     ///
292     /// ```rust
293     /// #![feature(provide_any)]
294     /// #![feature(error_generic_member_access)]
295     /// use core::fmt;
296     /// use core::any::Demand;
297     ///
298     /// #[derive(Debug)]
299     /// struct MyBacktrace {
300     ///     // ...
301     /// }
302     ///
303     /// impl MyBacktrace {
304     ///     fn new() -> MyBacktrace {
305     ///         // ...
306     ///         # MyBacktrace {}
307     ///     }
308     /// }
309     ///
310     /// #[derive(Debug)]
311     /// struct SourceError {
312     ///     // ...
313     /// }
314     ///
315     /// impl fmt::Display for SourceError {
316     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317     ///         write!(f, "Example Source Error")
318     ///     }
319     /// }
320     ///
321     /// impl std::error::Error for SourceError {}
322     ///
323     /// #[derive(Debug)]
324     /// struct Error {
325     ///     source: SourceError,
326     ///     backtrace: MyBacktrace,
327     /// }
328     ///
329     /// impl fmt::Display for Error {
330     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331     ///         write!(f, "Example Error")
332     ///     }
333     /// }
334     ///
335     /// impl std::error::Error for Error {
336     ///     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
337     ///         req
338     ///             .provide_ref::<MyBacktrace>(&self.backtrace)
339     ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
340     ///     }
341     /// }
342     ///
343     /// fn main() {
344     ///     let backtrace = MyBacktrace::new();
345     ///     let source = SourceError {};
346     ///     let error = Error { source, backtrace };
347     ///     let dyn_error = &error as &dyn std::error::Error;
348     ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
349     ///
350     ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
351     /// }
352     /// ```
353     #[unstable(feature = "error_generic_member_access", issue = "99301")]
354     #[allow(unused_variables)]
355     fn provide<'a>(&'a self, req: &mut Demand<'a>) {}
356 }
357
358 #[unstable(feature = "error_generic_member_access", issue = "99301")]
359 impl<'b> Provider for dyn Error + 'b {
360     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
361         self.provide(req)
362     }
363 }
364
365 mod private {
366     // This is a hack to prevent `type_id` from being overridden by `Error`
367     // implementations, since that can enable unsound downcasting.
368     #[unstable(feature = "error_type_id", issue = "60784")]
369     #[derive(Debug)]
370     pub struct Internal;
371 }
372
373 #[stable(feature = "rust1", since = "1.0.0")]
374 impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
375     /// Converts a type of [`Error`] into a box of dyn [`Error`].
376     ///
377     /// # Examples
378     ///
379     /// ```
380     /// use std::error::Error;
381     /// use std::fmt;
382     /// use std::mem;
383     ///
384     /// #[derive(Debug)]
385     /// struct AnError;
386     ///
387     /// impl fmt::Display for AnError {
388     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389     ///         write!(f, "An error")
390     ///     }
391     /// }
392     ///
393     /// impl Error for AnError {}
394     ///
395     /// let an_error = AnError;
396     /// assert!(0 == mem::size_of_val(&an_error));
397     /// let a_boxed_error = Box::<dyn Error>::from(an_error);
398     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
399     /// ```
400     fn from(err: E) -> Box<dyn Error + 'a> {
401         Box::new(err)
402     }
403 }
404
405 #[stable(feature = "rust1", since = "1.0.0")]
406 impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
407     /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
408     /// dyn [`Error`] + [`Send`] + [`Sync`].
409     ///
410     /// # Examples
411     ///
412     /// ```
413     /// use std::error::Error;
414     /// use std::fmt;
415     /// use std::mem;
416     ///
417     /// #[derive(Debug)]
418     /// struct AnError;
419     ///
420     /// impl fmt::Display for AnError {
421     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422     ///         write!(f, "An error")
423     ///     }
424     /// }
425     ///
426     /// impl Error for AnError {}
427     ///
428     /// unsafe impl Send for AnError {}
429     ///
430     /// unsafe impl Sync for AnError {}
431     ///
432     /// let an_error = AnError;
433     /// assert!(0 == mem::size_of_val(&an_error));
434     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
435     /// assert!(
436     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
437     /// ```
438     fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
439         Box::new(err)
440     }
441 }
442
443 #[stable(feature = "rust1", since = "1.0.0")]
444 impl From<String> for Box<dyn Error + Send + Sync> {
445     /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
446     ///
447     /// # Examples
448     ///
449     /// ```
450     /// use std::error::Error;
451     /// use std::mem;
452     ///
453     /// let a_string_error = "a string error".to_string();
454     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
455     /// assert!(
456     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
457     /// ```
458     #[inline]
459     fn from(err: String) -> Box<dyn Error + Send + Sync> {
460         struct StringError(String);
461
462         impl Error for StringError {
463             #[allow(deprecated)]
464             fn description(&self) -> &str {
465                 &self.0
466             }
467         }
468
469         impl Display for StringError {
470             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471                 Display::fmt(&self.0, f)
472             }
473         }
474
475         // Purposefully skip printing "StringError(..)"
476         impl Debug for StringError {
477             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478                 Debug::fmt(&self.0, f)
479             }
480         }
481
482         Box::new(StringError(err))
483     }
484 }
485
486 #[stable(feature = "string_box_error", since = "1.6.0")]
487 impl From<String> for Box<dyn Error> {
488     /// Converts a [`String`] into a box of dyn [`Error`].
489     ///
490     /// # Examples
491     ///
492     /// ```
493     /// use std::error::Error;
494     /// use std::mem;
495     ///
496     /// let a_string_error = "a string error".to_string();
497     /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
498     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
499     /// ```
500     fn from(str_err: String) -> Box<dyn Error> {
501         let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
502         let err2: Box<dyn Error> = err1;
503         err2
504     }
505 }
506
507 #[stable(feature = "rust1", since = "1.0.0")]
508 impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
509     /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
510     ///
511     /// [`str`]: prim@str
512     ///
513     /// # Examples
514     ///
515     /// ```
516     /// use std::error::Error;
517     /// use std::mem;
518     ///
519     /// let a_str_error = "a str error";
520     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
521     /// assert!(
522     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
523     /// ```
524     #[inline]
525     fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
526         From::from(String::from(err))
527     }
528 }
529
530 #[stable(feature = "string_box_error", since = "1.6.0")]
531 impl From<&str> for Box<dyn Error> {
532     /// Converts a [`str`] into a box of dyn [`Error`].
533     ///
534     /// [`str`]: prim@str
535     ///
536     /// # Examples
537     ///
538     /// ```
539     /// use std::error::Error;
540     /// use std::mem;
541     ///
542     /// let a_str_error = "a str error";
543     /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
544     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
545     /// ```
546     fn from(err: &str) -> Box<dyn Error> {
547         From::from(String::from(err))
548     }
549 }
550
551 #[stable(feature = "cow_box_error", since = "1.22.0")]
552 impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
553     /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
554     ///
555     /// # Examples
556     ///
557     /// ```
558     /// use std::error::Error;
559     /// use std::mem;
560     /// use std::borrow::Cow;
561     ///
562     /// let a_cow_str_error = Cow::from("a str error");
563     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
564     /// assert!(
565     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
566     /// ```
567     fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
568         From::from(String::from(err))
569     }
570 }
571
572 #[stable(feature = "cow_box_error", since = "1.22.0")]
573 impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
574     /// Converts a [`Cow`] into a box of dyn [`Error`].
575     ///
576     /// # Examples
577     ///
578     /// ```
579     /// use std::error::Error;
580     /// use std::mem;
581     /// use std::borrow::Cow;
582     ///
583     /// let a_cow_str_error = Cow::from("a str error");
584     /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
585     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
586     /// ```
587     fn from(err: Cow<'a, str>) -> Box<dyn Error> {
588         From::from(String::from(err))
589     }
590 }
591
592 #[unstable(feature = "never_type", issue = "35121")]
593 impl Error for ! {}
594
595 #[unstable(
596     feature = "allocator_api",
597     reason = "the precise API and guarantees it provides may be tweaked.",
598     issue = "32838"
599 )]
600 impl Error for AllocError {}
601
602 #[stable(feature = "alloc_layout", since = "1.28.0")]
603 impl Error for LayoutError {}
604
605 #[stable(feature = "rust1", since = "1.0.0")]
606 impl Error for str::ParseBoolError {
607     #[allow(deprecated)]
608     fn description(&self) -> &str {
609         "failed to parse bool"
610     }
611 }
612
613 #[stable(feature = "rust1", since = "1.0.0")]
614 impl Error for str::Utf8Error {
615     #[allow(deprecated)]
616     fn description(&self) -> &str {
617         "invalid utf-8: corrupt contents"
618     }
619 }
620
621 #[stable(feature = "rust1", since = "1.0.0")]
622 impl Error for num::ParseIntError {
623     #[allow(deprecated)]
624     fn description(&self) -> &str {
625         self.__description()
626     }
627 }
628
629 #[stable(feature = "try_from", since = "1.34.0")]
630 impl Error for num::TryFromIntError {
631     #[allow(deprecated)]
632     fn description(&self) -> &str {
633         self.__description()
634     }
635 }
636
637 #[stable(feature = "try_from", since = "1.34.0")]
638 impl Error for array::TryFromSliceError {
639     #[allow(deprecated)]
640     fn description(&self) -> &str {
641         self.__description()
642     }
643 }
644
645 #[stable(feature = "rust1", since = "1.0.0")]
646 impl Error for num::ParseFloatError {
647     #[allow(deprecated)]
648     fn description(&self) -> &str {
649         self.__description()
650     }
651 }
652
653 #[stable(feature = "rust1", since = "1.0.0")]
654 impl Error for string::FromUtf8Error {
655     #[allow(deprecated)]
656     fn description(&self) -> &str {
657         "invalid utf-8"
658     }
659 }
660
661 #[stable(feature = "rust1", since = "1.0.0")]
662 impl Error for string::FromUtf16Error {
663     #[allow(deprecated)]
664     fn description(&self) -> &str {
665         "invalid utf-16"
666     }
667 }
668
669 #[stable(feature = "str_parse_error2", since = "1.8.0")]
670 impl Error for Infallible {
671     fn description(&self) -> &str {
672         match *self {}
673     }
674 }
675
676 #[stable(feature = "decode_utf16", since = "1.9.0")]
677 impl Error for char::DecodeUtf16Error {
678     #[allow(deprecated)]
679     fn description(&self) -> &str {
680         "unpaired surrogate found"
681     }
682 }
683
684 #[stable(feature = "u8_from_char", since = "1.59.0")]
685 impl Error for char::TryFromCharError {}
686
687 #[unstable(feature = "map_try_insert", issue = "82766")]
688 impl<'a, K: Debug + Ord, V: Debug> Error
689     for crate::collections::btree_map::OccupiedError<'a, K, V>
690 {
691     #[allow(deprecated)]
692     fn description(&self) -> &str {
693         "key already exists"
694     }
695 }
696
697 #[unstable(feature = "map_try_insert", issue = "82766")]
698 impl<'a, K: Debug, V: Debug> Error for crate::collections::hash_map::OccupiedError<'a, K, V> {
699     #[allow(deprecated)]
700     fn description(&self) -> &str {
701         "key already exists"
702     }
703 }
704
705 #[stable(feature = "box_error", since = "1.8.0")]
706 impl<T: Error> Error for Box<T> {
707     #[allow(deprecated, deprecated_in_future)]
708     fn description(&self) -> &str {
709         Error::description(&**self)
710     }
711
712     #[allow(deprecated)]
713     fn cause(&self) -> Option<&dyn Error> {
714         Error::cause(&**self)
715     }
716
717     fn source(&self) -> Option<&(dyn Error + 'static)> {
718         Error::source(&**self)
719     }
720 }
721
722 #[unstable(feature = "thin_box", issue = "92791")]
723 impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::ThinBox<T> {
724     fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> {
725         use core::ops::Deref;
726         self.deref().source()
727     }
728 }
729
730 #[stable(feature = "error_by_ref", since = "1.51.0")]
731 impl<'a, T: Error + ?Sized> Error for &'a T {
732     #[allow(deprecated, deprecated_in_future)]
733     fn description(&self) -> &str {
734         Error::description(&**self)
735     }
736
737     #[allow(deprecated)]
738     fn cause(&self) -> Option<&dyn Error> {
739         Error::cause(&**self)
740     }
741
742     fn source(&self) -> Option<&(dyn Error + 'static)> {
743         Error::source(&**self)
744     }
745
746     fn provide<'b>(&'b self, req: &mut Demand<'b>) {
747         Error::provide(&**self, req);
748     }
749 }
750
751 #[stable(feature = "arc_error", since = "1.52.0")]
752 impl<T: Error + ?Sized> Error for Arc<T> {
753     #[allow(deprecated, deprecated_in_future)]
754     fn description(&self) -> &str {
755         Error::description(&**self)
756     }
757
758     #[allow(deprecated)]
759     fn cause(&self) -> Option<&dyn Error> {
760         Error::cause(&**self)
761     }
762
763     fn source(&self) -> Option<&(dyn Error + 'static)> {
764         Error::source(&**self)
765     }
766
767     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
768         Error::provide(&**self, req);
769     }
770 }
771
772 #[stable(feature = "fmt_error", since = "1.11.0")]
773 impl Error for fmt::Error {
774     #[allow(deprecated)]
775     fn description(&self) -> &str {
776         "an error occurred when formatting an argument"
777     }
778 }
779
780 #[stable(feature = "try_borrow", since = "1.13.0")]
781 impl Error for cell::BorrowError {
782     #[allow(deprecated)]
783     fn description(&self) -> &str {
784         "already mutably borrowed"
785     }
786 }
787
788 #[stable(feature = "try_borrow", since = "1.13.0")]
789 impl Error for cell::BorrowMutError {
790     #[allow(deprecated)]
791     fn description(&self) -> &str {
792         "already borrowed"
793     }
794 }
795
796 #[stable(feature = "try_from", since = "1.34.0")]
797 impl Error for char::CharTryFromError {
798     #[allow(deprecated)]
799     fn description(&self) -> &str {
800         "converted integer out of range for `char`"
801     }
802 }
803
804 #[stable(feature = "char_from_str", since = "1.20.0")]
805 impl Error for char::ParseCharError {
806     #[allow(deprecated)]
807     fn description(&self) -> &str {
808         self.__description()
809     }
810 }
811
812 #[stable(feature = "try_reserve", since = "1.57.0")]
813 impl Error for alloc::collections::TryReserveError {}
814
815 #[unstable(feature = "duration_checked_float", issue = "83400")]
816 impl Error for time::FromFloatSecsError {}
817
818 #[stable(feature = "rust1", since = "1.0.0")]
819 impl Error for alloc::ffi::NulError {
820     #[allow(deprecated)]
821     fn description(&self) -> &str {
822         "nul byte found in data"
823     }
824 }
825
826 #[stable(feature = "rust1", since = "1.0.0")]
827 impl From<alloc::ffi::NulError> for io::Error {
828     /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`].
829     fn from(_: alloc::ffi::NulError) -> io::Error {
830         io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
831     }
832 }
833
834 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
835 impl Error for core::ffi::FromBytesWithNulError {
836     #[allow(deprecated)]
837     fn description(&self) -> &str {
838         self.__description()
839     }
840 }
841
842 #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
843 impl Error for core::ffi::FromBytesUntilNulError {}
844
845 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
846 impl Error for alloc::ffi::FromVecWithNulError {}
847
848 #[stable(feature = "cstring_into", since = "1.7.0")]
849 impl Error for alloc::ffi::IntoStringError {
850     #[allow(deprecated)]
851     fn description(&self) -> &str {
852         "C string contained non-utf8 bytes"
853     }
854
855     fn source(&self) -> Option<&(dyn Error + 'static)> {
856         Some(self.__source())
857     }
858 }
859
860 impl<'a> dyn Error + 'a {
861     /// Request a reference of type `T` as context about this error.
862     #[unstable(feature = "error_generic_member_access", issue = "99301")]
863     pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
864         core::any::request_ref(self)
865     }
866
867     /// Request a value of type `T` as context about this error.
868     #[unstable(feature = "error_generic_member_access", issue = "99301")]
869     pub fn request_value<T: 'static>(&'a self) -> Option<T> {
870         core::any::request_value(self)
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
915 impl dyn Error + 'static + Send {
916     /// Forwards to the method defined on the type `dyn Error`.
917     #[stable(feature = "error_downcast", since = "1.3.0")]
918     #[inline]
919     pub fn is<T: Error + 'static>(&self) -> bool {
920         <dyn Error + 'static>::is::<T>(self)
921     }
922
923     /// Forwards to the method defined on the type `dyn Error`.
924     #[stable(feature = "error_downcast", since = "1.3.0")]
925     #[inline]
926     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
927         <dyn Error + 'static>::downcast_ref::<T>(self)
928     }
929
930     /// Forwards to the method defined on the type `dyn Error`.
931     #[stable(feature = "error_downcast", since = "1.3.0")]
932     #[inline]
933     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
934         <dyn Error + 'static>::downcast_mut::<T>(self)
935     }
936
937     /// Request a reference of type `T` as context about this error.
938     #[unstable(feature = "error_generic_member_access", issue = "99301")]
939     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
940         <dyn Error>::request_ref(self)
941     }
942
943     /// Request a value of type `T` as context about this error.
944     #[unstable(feature = "error_generic_member_access", issue = "99301")]
945     pub fn request_value<T: 'static>(&self) -> Option<T> {
946         <dyn Error>::request_value(self)
947     }
948 }
949
950 impl dyn Error + 'static + Send + Sync {
951     /// Forwards to the method defined on the type `dyn Error`.
952     #[stable(feature = "error_downcast", since = "1.3.0")]
953     #[inline]
954     pub fn is<T: Error + 'static>(&self) -> bool {
955         <dyn Error + 'static>::is::<T>(self)
956     }
957
958     /// Forwards to the method defined on the type `dyn Error`.
959     #[stable(feature = "error_downcast", since = "1.3.0")]
960     #[inline]
961     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
962         <dyn Error + 'static>::downcast_ref::<T>(self)
963     }
964
965     /// Forwards to the method defined on the type `dyn Error`.
966     #[stable(feature = "error_downcast", since = "1.3.0")]
967     #[inline]
968     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
969         <dyn Error + 'static>::downcast_mut::<T>(self)
970     }
971
972     /// Request a reference of type `T` as context about this error.
973     #[unstable(feature = "error_generic_member_access", issue = "99301")]
974     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
975         <dyn Error>::request_ref(self)
976     }
977
978     /// Request a value of type `T` as context about this error.
979     #[unstable(feature = "error_generic_member_access", issue = "99301")]
980     pub fn request_value<T: 'static>(&self) -> Option<T> {
981         <dyn Error>::request_value(self)
982     }
983 }
984
985 impl dyn Error {
986     #[inline]
987     #[stable(feature = "error_downcast", since = "1.3.0")]
988     /// Attempts to downcast the box to a concrete type.
989     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
990         if self.is::<T>() {
991             unsafe {
992                 let raw: *mut dyn Error = Box::into_raw(self);
993                 Ok(Box::from_raw(raw as *mut T))
994             }
995         } else {
996             Err(self)
997         }
998     }
999
1000     /// Returns an iterator starting with the current error and continuing with
1001     /// recursively calling [`Error::source`].
1002     ///
1003     /// If you want to omit the current error and only use its sources,
1004     /// use `skip(1)`.
1005     ///
1006     /// # Examples
1007     ///
1008     /// ```
1009     /// #![feature(error_iter)]
1010     /// use std::error::Error;
1011     /// use std::fmt;
1012     ///
1013     /// #[derive(Debug)]
1014     /// struct A;
1015     ///
1016     /// #[derive(Debug)]
1017     /// struct B(Option<Box<dyn Error + 'static>>);
1018     ///
1019     /// impl fmt::Display for A {
1020     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1021     ///         write!(f, "A")
1022     ///     }
1023     /// }
1024     ///
1025     /// impl fmt::Display for B {
1026     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027     ///         write!(f, "B")
1028     ///     }
1029     /// }
1030     ///
1031     /// impl Error for A {}
1032     ///
1033     /// impl Error for B {
1034     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
1035     ///         self.0.as_ref().map(|e| e.as_ref())
1036     ///     }
1037     /// }
1038     ///
1039     /// let b = B(Some(Box::new(A)));
1040     ///
1041     /// // let err : Box<Error> = b.into(); // or
1042     /// let err = &b as &(dyn Error);
1043     ///
1044     /// let mut iter = err.chain();
1045     ///
1046     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
1047     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
1048     /// assert!(iter.next().is_none());
1049     /// assert!(iter.next().is_none());
1050     /// ```
1051     #[unstable(feature = "error_iter", issue = "58520")]
1052     #[inline]
1053     pub fn chain(&self) -> Chain<'_> {
1054         Chain { current: Some(self) }
1055     }
1056 }
1057
1058 /// An iterator over an [`Error`] and its sources.
1059 ///
1060 /// If you want to omit the initial error and only process
1061 /// its sources, use `skip(1)`.
1062 #[unstable(feature = "error_iter", issue = "58520")]
1063 #[derive(Clone, Debug)]
1064 pub struct Chain<'a> {
1065     current: Option<&'a (dyn Error + 'static)>,
1066 }
1067
1068 #[unstable(feature = "error_iter", issue = "58520")]
1069 impl<'a> Iterator for Chain<'a> {
1070     type Item = &'a (dyn Error + 'static);
1071
1072     fn next(&mut self) -> Option<Self::Item> {
1073         let current = self.current;
1074         self.current = self.current.and_then(Error::source);
1075         current
1076     }
1077 }
1078
1079 impl dyn Error + Send {
1080     #[inline]
1081     #[stable(feature = "error_downcast", since = "1.3.0")]
1082     /// Attempts to downcast the box to a concrete type.
1083     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
1084         let err: Box<dyn Error> = self;
1085         <dyn Error>::downcast(err).map_err(|s| unsafe {
1086             // Reapply the `Send` marker.
1087             transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
1088         })
1089     }
1090 }
1091
1092 impl dyn Error + Send + Sync {
1093     #[inline]
1094     #[stable(feature = "error_downcast", since = "1.3.0")]
1095     /// Attempts to downcast the box to a concrete type.
1096     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
1097         let err: Box<dyn Error> = self;
1098         <dyn Error>::downcast(err).map_err(|s| unsafe {
1099             // Reapply the `Send + Sync` marker.
1100             transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
1101         })
1102     }
1103 }
1104
1105 /// An error reporter that prints an error and its sources.
1106 ///
1107 /// Report also exposes configuration options for formatting the error chain, either entirely on a
1108 /// single line, or in multi-line format with each cause in the error chain on a new line.
1109 ///
1110 /// `Report` only requires that the wrapped error implement `Error`. It doesn't require that the
1111 /// wrapped error be `Send`, `Sync`, or `'static`.
1112 ///
1113 /// # Examples
1114 ///
1115 /// ```rust
1116 /// #![feature(error_reporter)]
1117 /// use std::error::{Error, Report};
1118 /// use std::fmt;
1119 ///
1120 /// #[derive(Debug)]
1121 /// struct SuperError {
1122 ///     source: SuperErrorSideKick,
1123 /// }
1124 ///
1125 /// impl fmt::Display for SuperError {
1126 ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1127 ///         write!(f, "SuperError is here!")
1128 ///     }
1129 /// }
1130 ///
1131 /// impl Error for SuperError {
1132 ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
1133 ///         Some(&self.source)
1134 ///     }
1135 /// }
1136 ///
1137 /// #[derive(Debug)]
1138 /// struct SuperErrorSideKick;
1139 ///
1140 /// impl fmt::Display for SuperErrorSideKick {
1141 ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1142 ///         write!(f, "SuperErrorSideKick is here!")
1143 ///     }
1144 /// }
1145 ///
1146 /// impl Error for SuperErrorSideKick {}
1147 ///
1148 /// fn get_super_error() -> Result<(), SuperError> {
1149 ///     Err(SuperError { source: SuperErrorSideKick })
1150 /// }
1151 ///
1152 /// fn main() {
1153 ///     match get_super_error() {
1154 ///         Err(e) => println!("Error: {}", Report::new(e)),
1155 ///         _ => println!("No error"),
1156 ///     }
1157 /// }
1158 /// ```
1159 ///
1160 /// This example produces the following output:
1161 ///
1162 /// ```console
1163 /// Error: SuperError is here!: SuperErrorSideKick is here!
1164 /// ```
1165 ///
1166 /// ## Output consistency
1167 ///
1168 /// Report prints the same output via `Display` and `Debug`, so it works well with
1169 /// [`Result::unwrap`]/[`Result::expect`] which print their `Err` variant via `Debug`:
1170 ///
1171 /// ```should_panic
1172 /// #![feature(error_reporter)]
1173 /// use std::error::Report;
1174 /// # use std::error::Error;
1175 /// # use std::fmt;
1176 /// # #[derive(Debug)]
1177 /// # struct SuperError {
1178 /// #     source: SuperErrorSideKick,
1179 /// # }
1180 /// # impl fmt::Display for SuperError {
1181 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1182 /// #         write!(f, "SuperError is here!")
1183 /// #     }
1184 /// # }
1185 /// # impl Error for SuperError {
1186 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1187 /// #         Some(&self.source)
1188 /// #     }
1189 /// # }
1190 /// # #[derive(Debug)]
1191 /// # struct SuperErrorSideKick;
1192 /// # impl fmt::Display for SuperErrorSideKick {
1193 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1194 /// #         write!(f, "SuperErrorSideKick is here!")
1195 /// #     }
1196 /// # }
1197 /// # impl Error for SuperErrorSideKick {}
1198 /// # fn get_super_error() -> Result<(), SuperError> {
1199 /// #     Err(SuperError { source: SuperErrorSideKick })
1200 /// # }
1201 ///
1202 /// get_super_error().map_err(Report::new).unwrap();
1203 /// ```
1204 ///
1205 /// This example produces the following output:
1206 ///
1207 /// ```console
1208 /// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SuperError is here!: SuperErrorSideKick is here!', src/error.rs:34:40
1209 /// note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1210 /// ```
1211 ///
1212 /// ## Return from `main`
1213 ///
1214 /// `Report` also implements `From` for all types that implement [`Error`]; this when combined with
1215 /// the `Debug` output means `Report` is an ideal starting place for formatting errors returned
1216 /// from `main`.
1217 ///
1218 /// ```should_panic
1219 /// #![feature(error_reporter)]
1220 /// use std::error::Report;
1221 /// # use std::error::Error;
1222 /// # use std::fmt;
1223 /// # #[derive(Debug)]
1224 /// # struct SuperError {
1225 /// #     source: SuperErrorSideKick,
1226 /// # }
1227 /// # impl fmt::Display for SuperError {
1228 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1229 /// #         write!(f, "SuperError is here!")
1230 /// #     }
1231 /// # }
1232 /// # impl Error for SuperError {
1233 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1234 /// #         Some(&self.source)
1235 /// #     }
1236 /// # }
1237 /// # #[derive(Debug)]
1238 /// # struct SuperErrorSideKick;
1239 /// # impl fmt::Display for SuperErrorSideKick {
1240 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1241 /// #         write!(f, "SuperErrorSideKick is here!")
1242 /// #     }
1243 /// # }
1244 /// # impl Error for SuperErrorSideKick {}
1245 /// # fn get_super_error() -> Result<(), SuperError> {
1246 /// #     Err(SuperError { source: SuperErrorSideKick })
1247 /// # }
1248 ///
1249 /// fn main() -> Result<(), Report> {
1250 ///     get_super_error()?;
1251 ///     Ok(())
1252 /// }
1253 /// ```
1254 ///
1255 /// This example produces the following output:
1256 ///
1257 /// ```console
1258 /// Error: SuperError is here!: SuperErrorSideKick is here!
1259 /// ```
1260 ///
1261 /// **Note**: `Report`s constructed via `?` and `From` will be configured to use the single line
1262 /// output format. If you want to make sure your `Report`s are pretty printed and include backtrace
1263 /// you will need to manually convert and enable those flags.
1264 ///
1265 /// ```should_panic
1266 /// #![feature(error_reporter)]
1267 /// use std::error::Report;
1268 /// # use std::error::Error;
1269 /// # use std::fmt;
1270 /// # #[derive(Debug)]
1271 /// # struct SuperError {
1272 /// #     source: SuperErrorSideKick,
1273 /// # }
1274 /// # impl fmt::Display for SuperError {
1275 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1276 /// #         write!(f, "SuperError is here!")
1277 /// #     }
1278 /// # }
1279 /// # impl Error for SuperError {
1280 /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1281 /// #         Some(&self.source)
1282 /// #     }
1283 /// # }
1284 /// # #[derive(Debug)]
1285 /// # struct SuperErrorSideKick;
1286 /// # impl fmt::Display for SuperErrorSideKick {
1287 /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1288 /// #         write!(f, "SuperErrorSideKick is here!")
1289 /// #     }
1290 /// # }
1291 /// # impl Error for SuperErrorSideKick {}
1292 /// # fn get_super_error() -> Result<(), SuperError> {
1293 /// #     Err(SuperError { source: SuperErrorSideKick })
1294 /// # }
1295 ///
1296 /// fn main() -> Result<(), Report> {
1297 ///     get_super_error()
1298 ///         .map_err(Report::from)
1299 ///         .map_err(|r| r.pretty(true).show_backtrace(true))?;
1300 ///     Ok(())
1301 /// }
1302 /// ```
1303 ///
1304 /// This example produces the following output:
1305 ///
1306 /// ```console
1307 /// Error: SuperError is here!
1308 ///
1309 /// Caused by:
1310 ///       SuperErrorSideKick is here!
1311 /// ```
1312 #[unstable(feature = "error_reporter", issue = "90172")]
1313 pub struct Report<E = Box<dyn Error>> {
1314     /// The error being reported.
1315     error: E,
1316     /// Whether a backtrace should be included as part of the report.
1317     show_backtrace: bool,
1318     /// Whether the report should be pretty-printed.
1319     pretty: bool,
1320 }
1321
1322 impl<E> Report<E>
1323 where
1324     Report<E>: From<E>,
1325 {
1326     /// Create a new `Report` from an input error.
1327     #[unstable(feature = "error_reporter", issue = "90172")]
1328     pub fn new(error: E) -> Report<E> {
1329         Self::from(error)
1330     }
1331 }
1332
1333 impl<E> Report<E> {
1334     /// Enable pretty-printing the report across multiple lines.
1335     ///
1336     /// # Examples
1337     ///
1338     /// ```rust
1339     /// #![feature(error_reporter)]
1340     /// use std::error::Report;
1341     /// # use std::error::Error;
1342     /// # use std::fmt;
1343     /// # #[derive(Debug)]
1344     /// # struct SuperError {
1345     /// #     source: SuperErrorSideKick,
1346     /// # }
1347     /// # impl fmt::Display for SuperError {
1348     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1349     /// #         write!(f, "SuperError is here!")
1350     /// #     }
1351     /// # }
1352     /// # impl Error for SuperError {
1353     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1354     /// #         Some(&self.source)
1355     /// #     }
1356     /// # }
1357     /// # #[derive(Debug)]
1358     /// # struct SuperErrorSideKick;
1359     /// # impl fmt::Display for SuperErrorSideKick {
1360     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1361     /// #         write!(f, "SuperErrorSideKick is here!")
1362     /// #     }
1363     /// # }
1364     /// # impl Error for SuperErrorSideKick {}
1365     ///
1366     /// let error = SuperError { source: SuperErrorSideKick };
1367     /// let report = Report::new(error).pretty(true);
1368     /// eprintln!("Error: {report:?}");
1369     /// ```
1370     ///
1371     /// This example produces the following output:
1372     ///
1373     /// ```console
1374     /// Error: SuperError is here!
1375     ///
1376     /// Caused by:
1377     ///       SuperErrorSideKick is here!
1378     /// ```
1379     ///
1380     /// When there are multiple source errors the causes will be numbered in order of iteration
1381     /// starting from the outermost error.
1382     ///
1383     /// ```rust
1384     /// #![feature(error_reporter)]
1385     /// use std::error::Report;
1386     /// # use std::error::Error;
1387     /// # use std::fmt;
1388     /// # #[derive(Debug)]
1389     /// # struct SuperError {
1390     /// #     source: SuperErrorSideKick,
1391     /// # }
1392     /// # impl fmt::Display for SuperError {
1393     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1394     /// #         write!(f, "SuperError is here!")
1395     /// #     }
1396     /// # }
1397     /// # impl Error for SuperError {
1398     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1399     /// #         Some(&self.source)
1400     /// #     }
1401     /// # }
1402     /// # #[derive(Debug)]
1403     /// # struct SuperErrorSideKick {
1404     /// #     source: SuperErrorSideKickSideKick,
1405     /// # }
1406     /// # impl fmt::Display for SuperErrorSideKick {
1407     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1408     /// #         write!(f, "SuperErrorSideKick is here!")
1409     /// #     }
1410     /// # }
1411     /// # impl Error for SuperErrorSideKick {
1412     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1413     /// #         Some(&self.source)
1414     /// #     }
1415     /// # }
1416     /// # #[derive(Debug)]
1417     /// # struct SuperErrorSideKickSideKick;
1418     /// # impl fmt::Display for SuperErrorSideKickSideKick {
1419     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1420     /// #         write!(f, "SuperErrorSideKickSideKick is here!")
1421     /// #     }
1422     /// # }
1423     /// # impl Error for SuperErrorSideKickSideKick { }
1424     ///
1425     /// let source = SuperErrorSideKickSideKick;
1426     /// let source = SuperErrorSideKick { source };
1427     /// let error = SuperError { source };
1428     /// let report = Report::new(error).pretty(true);
1429     /// eprintln!("Error: {report:?}");
1430     /// ```
1431     ///
1432     /// This example produces the following output:
1433     ///
1434     /// ```console
1435     /// Error: SuperError is here!
1436     ///
1437     /// Caused by:
1438     ///    0: SuperErrorSideKick is here!
1439     ///    1: SuperErrorSideKickSideKick is here!
1440     /// ```
1441     #[unstable(feature = "error_reporter", issue = "90172")]
1442     pub fn pretty(mut self, pretty: bool) -> Self {
1443         self.pretty = pretty;
1444         self
1445     }
1446
1447     /// Display backtrace if available when using pretty output format.
1448     ///
1449     /// # Examples
1450     ///
1451     /// **Note**: Report will search for the first `Backtrace` it can find starting from the
1452     /// outermost error. In this example it will display the backtrace from the second error in the
1453     /// chain, `SuperErrorSideKick`.
1454     ///
1455     /// ```rust
1456     /// #![feature(error_reporter)]
1457     /// #![feature(provide_any)]
1458     /// #![feature(error_generic_member_access)]
1459     /// # use std::error::Error;
1460     /// # use std::fmt;
1461     /// use std::any::Demand;
1462     /// use std::error::Report;
1463     /// use std::backtrace::Backtrace;
1464     ///
1465     /// # #[derive(Debug)]
1466     /// # struct SuperError {
1467     /// #     source: SuperErrorSideKick,
1468     /// # }
1469     /// # impl fmt::Display for SuperError {
1470     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1471     /// #         write!(f, "SuperError is here!")
1472     /// #     }
1473     /// # }
1474     /// # impl Error for SuperError {
1475     /// #     fn source(&self) -> Option<&(dyn Error + 'static)> {
1476     /// #         Some(&self.source)
1477     /// #     }
1478     /// # }
1479     /// #[derive(Debug)]
1480     /// struct SuperErrorSideKick {
1481     ///     backtrace: Backtrace,
1482     /// }
1483     ///
1484     /// impl SuperErrorSideKick {
1485     ///     fn new() -> SuperErrorSideKick {
1486     ///         SuperErrorSideKick { backtrace: Backtrace::force_capture() }
1487     ///     }
1488     /// }
1489     ///
1490     /// impl Error for SuperErrorSideKick {
1491     ///     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
1492     ///         req
1493     ///             .provide_ref::<Backtrace>(&self.backtrace);
1494     ///     }
1495     /// }
1496     ///
1497     /// // The rest of the example is unchanged ...
1498     /// # impl fmt::Display for SuperErrorSideKick {
1499     /// #     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1500     /// #         write!(f, "SuperErrorSideKick is here!")
1501     /// #     }
1502     /// # }
1503     ///
1504     /// let source = SuperErrorSideKick::new();
1505     /// let error = SuperError { source };
1506     /// let report = Report::new(error).pretty(true).show_backtrace(true);
1507     /// eprintln!("Error: {report:?}");
1508     /// ```
1509     ///
1510     /// This example produces something similar to the following output:
1511     ///
1512     /// ```console
1513     /// Error: SuperError is here!
1514     ///
1515     /// Caused by:
1516     ///       SuperErrorSideKick is here!
1517     ///
1518     /// Stack backtrace:
1519     ///    0: rust_out::main::_doctest_main_src_error_rs_1158_0::SuperErrorSideKick::new
1520     ///    1: rust_out::main::_doctest_main_src_error_rs_1158_0
1521     ///    2: rust_out::main
1522     ///    3: core::ops::function::FnOnce::call_once
1523     ///    4: std::sys_common::backtrace::__rust_begin_short_backtrace
1524     ///    5: std::rt::lang_start::{{closure}}
1525     ///    6: std::panicking::try
1526     ///    7: std::rt::lang_start_internal
1527     ///    8: std::rt::lang_start
1528     ///    9: main
1529     ///   10: __libc_start_main
1530     ///   11: _start
1531     /// ```
1532     #[unstable(feature = "error_reporter", issue = "90172")]
1533     pub fn show_backtrace(mut self, show_backtrace: bool) -> Self {
1534         self.show_backtrace = show_backtrace;
1535         self
1536     }
1537 }
1538
1539 impl<E> Report<E>
1540 where
1541     E: Error,
1542 {
1543     fn backtrace(&self) -> Option<&Backtrace> {
1544         // have to grab the backtrace on the first error directly since that error may not be
1545         // 'static
1546         let backtrace = (&self.error as &dyn Error).request_ref();
1547         let backtrace = backtrace.or_else(|| {
1548             self.error
1549                 .source()
1550                 .map(|source| source.chain().find_map(|source| source.request_ref()))
1551                 .flatten()
1552         });
1553         backtrace
1554     }
1555
1556     /// Format the report as a single line.
1557     #[unstable(feature = "error_reporter", issue = "90172")]
1558     fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1559         write!(f, "{}", self.error)?;
1560
1561         let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
1562
1563         for cause in sources {
1564             write!(f, ": {cause}")?;
1565         }
1566
1567         Ok(())
1568     }
1569
1570     /// Format the report as multiple lines, with each error cause on its own line.
1571     #[unstable(feature = "error_reporter", issue = "90172")]
1572     fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1573         let error = &self.error;
1574
1575         write!(f, "{error}")?;
1576
1577         if let Some(cause) = error.source() {
1578             write!(f, "\n\nCaused by:")?;
1579
1580             let multiple = cause.source().is_some();
1581
1582             for (ind, error) in cause.chain().enumerate() {
1583                 writeln!(f)?;
1584                 let mut indented = Indented { inner: f };
1585                 if multiple {
1586                     write!(indented, "{ind: >4}: {error}")?;
1587                 } else {
1588                     write!(indented, "      {error}")?;
1589                 }
1590             }
1591         }
1592
1593         if self.show_backtrace {
1594             let backtrace = self.backtrace();
1595
1596             if let Some(backtrace) = backtrace {
1597                 let backtrace = backtrace.to_string();
1598
1599                 f.write_str("\n\nStack backtrace:\n")?;
1600                 f.write_str(backtrace.trim_end())?;
1601             }
1602         }
1603
1604         Ok(())
1605     }
1606 }
1607
1608 impl Report<Box<dyn Error>> {
1609     fn backtrace(&self) -> Option<&Backtrace> {
1610         // have to grab the backtrace on the first error directly since that error may not be
1611         // 'static
1612         let backtrace = self.error.request_ref();
1613         let backtrace = backtrace.or_else(|| {
1614             self.error
1615                 .source()
1616                 .map(|source| source.chain().find_map(|source| source.request_ref()))
1617                 .flatten()
1618         });
1619         backtrace
1620     }
1621
1622     /// Format the report as a single line.
1623     #[unstable(feature = "error_reporter", issue = "90172")]
1624     fn fmt_singleline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1625         write!(f, "{}", self.error)?;
1626
1627         let sources = self.error.source().into_iter().flat_map(<dyn Error>::chain);
1628
1629         for cause in sources {
1630             write!(f, ": {cause}")?;
1631         }
1632
1633         Ok(())
1634     }
1635
1636     /// Format the report as multiple lines, with each error cause on its own line.
1637     #[unstable(feature = "error_reporter", issue = "90172")]
1638     fn fmt_multiline(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1639         let error = &self.error;
1640
1641         write!(f, "{error}")?;
1642
1643         if let Some(cause) = error.source() {
1644             write!(f, "\n\nCaused by:")?;
1645
1646             let multiple = cause.source().is_some();
1647
1648             for (ind, error) in cause.chain().enumerate() {
1649                 writeln!(f)?;
1650                 let mut indented = Indented { inner: f };
1651                 if multiple {
1652                     write!(indented, "{ind: >4}: {error}")?;
1653                 } else {
1654                     write!(indented, "      {error}")?;
1655                 }
1656             }
1657         }
1658
1659         if self.show_backtrace {
1660             let backtrace = self.backtrace();
1661
1662             if let Some(backtrace) = backtrace {
1663                 let backtrace = backtrace.to_string();
1664
1665                 f.write_str("\n\nStack backtrace:\n")?;
1666                 f.write_str(backtrace.trim_end())?;
1667             }
1668         }
1669
1670         Ok(())
1671     }
1672 }
1673
1674 #[unstable(feature = "error_reporter", issue = "90172")]
1675 impl<E> From<E> for Report<E>
1676 where
1677     E: Error,
1678 {
1679     fn from(error: E) -> Self {
1680         Report { error, show_backtrace: false, pretty: false }
1681     }
1682 }
1683
1684 #[unstable(feature = "error_reporter", issue = "90172")]
1685 impl<'a, E> From<E> for Report<Box<dyn Error + 'a>>
1686 where
1687     E: Error + 'a,
1688 {
1689     fn from(error: E) -> Self {
1690         let error = box error;
1691         Report { error, show_backtrace: false, pretty: false }
1692     }
1693 }
1694
1695 #[unstable(feature = "error_reporter", issue = "90172")]
1696 impl<E> fmt::Display for Report<E>
1697 where
1698     E: Error,
1699 {
1700     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1701         if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
1702     }
1703 }
1704
1705 #[unstable(feature = "error_reporter", issue = "90172")]
1706 impl fmt::Display for Report<Box<dyn Error>> {
1707     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1708         if self.pretty { self.fmt_multiline(f) } else { self.fmt_singleline(f) }
1709     }
1710 }
1711
1712 // This type intentionally outputs the same format for `Display` and `Debug`for
1713 // situations where you unwrap a `Report` or return it from main.
1714 #[unstable(feature = "error_reporter", issue = "90172")]
1715 impl<E> fmt::Debug for Report<E>
1716 where
1717     Report<E>: fmt::Display,
1718 {
1719     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1720         fmt::Display::fmt(self, f)
1721     }
1722 }
1723
1724 /// Wrapper type for indenting the inner source.
1725 struct Indented<'a, D> {
1726     inner: &'a mut D,
1727 }
1728
1729 impl<T> Write for Indented<'_, T>
1730 where
1731     T: Write,
1732 {
1733     fn write_str(&mut self, s: &str) -> fmt::Result {
1734         for (i, line) in s.split('\n').enumerate() {
1735             if i > 0 {
1736                 self.inner.write_char('\n')?;
1737                 self.inner.write_str("      ")?;
1738             }
1739
1740             self.inner.write_str(line)?;
1741         }
1742
1743         Ok(())
1744     }
1745 }