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