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