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