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