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