1 use crate::alloc::Box;
2 use crate::backtrace::Backtrace;
3 use crate::chain::Chain;
4 use crate::{Error, StdError};
5 use core::any::TypeId;
6 use core::fmt::{self, Debug, Display};
7 use core::mem::{self, ManuallyDrop};
8 use core::ptr::{self, NonNull};
9 
10 #[cfg(feature = "std")]
11 use core::ops::{Deref, DerefMut};
12 
13 impl Error {
14     /// Create a new error object from any error type.
15     ///
16     /// The error type must be threadsafe and `'static`, so that the `Error`
17     /// will be as well.
18     ///
19     /// If the error type does not provide a backtrace, a backtrace will be
20     /// created here to ensure that a backtrace exists.
21     #[cfg(feature = "std")]
22     #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
new<E>(error: E) -> Self where E: StdError + Send + Sync + 'static,23     pub fn new<E>(error: E) -> Self
24     where
25         E: StdError + Send + Sync + 'static,
26     {
27         let backtrace = backtrace_if_absent!(error);
28         Error::from_std(error, backtrace)
29     }
30 
31     /// Create a new error object from a printable error message.
32     ///
33     /// If the argument implements std::error::Error, prefer `Error::new`
34     /// instead which preserves the underlying error's cause chain and
35     /// backtrace. If the argument may or may not implement std::error::Error
36     /// now or in the future, use `anyhow!(err)` which handles either way
37     /// correctly.
38     ///
39     /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
40     /// convenient in places where a function is preferable over a macro, such
41     /// as iterator or stream combinators:
42     ///
43     /// ```
44     /// # mod ffi {
45     /// #     pub struct Input;
46     /// #     pub struct Output;
47     /// #     pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
48     /// #         unimplemented!()
49     /// #     }
50     /// # }
51     /// #
52     /// # use ffi::{Input, Output};
53     /// #
54     /// use anyhow::{Error, Result};
55     /// use futures::stream::{Stream, StreamExt, TryStreamExt};
56     ///
57     /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
58     /// where
59     ///     S: Stream<Item = Input>,
60     /// {
61     ///     stream
62     ///         .then(ffi::do_some_work) // returns Result<Output, &str>
63     ///         .map_err(Error::msg)
64     ///         .try_collect()
65     ///         .await
66     /// }
67     /// ```
msg<M>(message: M) -> Self where M: Display + Debug + Send + Sync + 'static,68     pub fn msg<M>(message: M) -> Self
69     where
70         M: Display + Debug + Send + Sync + 'static,
71     {
72         Error::from_adhoc(message, backtrace!())
73     }
74 
75     #[cfg(feature = "std")]
from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self where E: StdError + Send + Sync + 'static,76     pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
77     where
78         E: StdError + Send + Sync + 'static,
79     {
80         let vtable = &ErrorVTable {
81             object_drop: object_drop::<E>,
82             object_ref: object_ref::<E>,
83             #[cfg(feature = "std")]
84             object_mut: object_mut::<E>,
85             object_boxed: object_boxed::<E>,
86             object_downcast: object_downcast::<E>,
87             object_drop_rest: object_drop_front::<E>,
88         };
89 
90         // Safety: passing vtable that operates on the right type E.
91         unsafe { Error::construct(error, vtable, backtrace) }
92     }
93 
from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self where M: Display + Debug + Send + Sync + 'static,94     pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
95     where
96         M: Display + Debug + Send + Sync + 'static,
97     {
98         use crate::wrapper::MessageError;
99         let error: MessageError<M> = MessageError(message);
100         let vtable = &ErrorVTable {
101             object_drop: object_drop::<MessageError<M>>,
102             object_ref: object_ref::<MessageError<M>>,
103             #[cfg(feature = "std")]
104             object_mut: object_mut::<MessageError<M>>,
105             object_boxed: object_boxed::<MessageError<M>>,
106             object_downcast: object_downcast::<M>,
107             object_drop_rest: object_drop_front::<M>,
108         };
109 
110         // Safety: MessageError is repr(transparent) so it is okay for the
111         // vtable to allow casting the MessageError<M> to M.
112         unsafe { Error::construct(error, vtable, backtrace) }
113     }
114 
from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self where M: Display + Send + Sync + 'static,115     pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
116     where
117         M: Display + Send + Sync + 'static,
118     {
119         use crate::wrapper::DisplayError;
120         let error: DisplayError<M> = DisplayError(message);
121         let vtable = &ErrorVTable {
122             object_drop: object_drop::<DisplayError<M>>,
123             object_ref: object_ref::<DisplayError<M>>,
124             #[cfg(feature = "std")]
125             object_mut: object_mut::<DisplayError<M>>,
126             object_boxed: object_boxed::<DisplayError<M>>,
127             object_downcast: object_downcast::<M>,
128             object_drop_rest: object_drop_front::<M>,
129         };
130 
131         // Safety: DisplayError is repr(transparent) so it is okay for the
132         // vtable to allow casting the DisplayError<M> to M.
133         unsafe { Error::construct(error, vtable, backtrace) }
134     }
135 
136     #[cfg(feature = "std")]
from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self where C: Display + Send + Sync + 'static, E: StdError + Send + Sync + 'static,137     pub(crate) fn from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self
138     where
139         C: Display + Send + Sync + 'static,
140         E: StdError + Send + Sync + 'static,
141     {
142         let error: ContextError<C, E> = ContextError { context, error };
143 
144         let vtable = &ErrorVTable {
145             object_drop: object_drop::<ContextError<C, E>>,
146             object_ref: object_ref::<ContextError<C, E>>,
147             #[cfg(feature = "std")]
148             object_mut: object_mut::<ContextError<C, E>>,
149             object_boxed: object_boxed::<ContextError<C, E>>,
150             object_downcast: context_downcast::<C, E>,
151             object_drop_rest: context_drop_rest::<C, E>,
152         };
153 
154         // Safety: passing vtable that operates on the right type.
155         unsafe { Error::construct(error, vtable, backtrace) }
156     }
157 
158     #[cfg(feature = "std")]
from_boxed( error: Box<dyn StdError + Send + Sync>, backtrace: Option<Backtrace>, ) -> Self159     pub(crate) fn from_boxed(
160         error: Box<dyn StdError + Send + Sync>,
161         backtrace: Option<Backtrace>,
162     ) -> Self {
163         use crate::wrapper::BoxedError;
164         let error = BoxedError(error);
165         let vtable = &ErrorVTable {
166             object_drop: object_drop::<BoxedError>,
167             object_ref: object_ref::<BoxedError>,
168             #[cfg(feature = "std")]
169             object_mut: object_mut::<BoxedError>,
170             object_boxed: object_boxed::<BoxedError>,
171             object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
172             object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
173         };
174 
175         // Safety: BoxedError is repr(transparent) so it is okay for the vtable
176         // to allow casting to Box<dyn StdError + Send + Sync>.
177         unsafe { Error::construct(error, vtable, backtrace) }
178     }
179 
180     // Takes backtrace as argument rather than capturing it here so that the
181     // user sees one fewer layer of wrapping noise in the backtrace.
182     //
183     // Unsafe because the given vtable must have sensible behavior on the error
184     // value of type E.
construct<E>( error: E, vtable: &'static ErrorVTable, backtrace: Option<Backtrace>, ) -> Self where E: StdError + Send + Sync + 'static,185     unsafe fn construct<E>(
186         error: E,
187         vtable: &'static ErrorVTable,
188         backtrace: Option<Backtrace>,
189     ) -> Self
190     where
191         E: StdError + Send + Sync + 'static,
192     {
193         let inner = Box::new(ErrorImpl {
194             vtable,
195             backtrace,
196             _object: error,
197         });
198         // Erase the concrete type of E from the compile-time type system. This
199         // is equivalent to the safe unsize coersion from Box<ErrorImpl<E>> to
200         // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
201         // result is a thin pointer. The necessary behavior for manipulating the
202         // underlying ErrorImpl<E> is preserved in the vtable provided by the
203         // caller rather than a builtin fat pointer vtable.
204         let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner);
205         let inner = ManuallyDrop::new(erased);
206         Error { inner }
207     }
208 
209     /// Wrap the error value with additional context.
210     ///
211     /// For attaching context to a `Result` as it is propagated, the
212     /// [`Context`][crate::Context] extension trait may be more convenient than
213     /// this function.
214     ///
215     /// The primary reason to use `error.context(...)` instead of
216     /// `result.context(...)` via the `Context` trait would be if the context
217     /// needs to depend on some data held by the underlying error:
218     ///
219     /// ```
220     /// # use std::fmt::{self, Debug, Display};
221     /// #
222     /// # type T = ();
223     /// #
224     /// # impl std::error::Error for ParseError {}
225     /// # impl Debug for ParseError {
226     /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
227     /// #         unimplemented!()
228     /// #     }
229     /// # }
230     /// # impl Display for ParseError {
231     /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
232     /// #         unimplemented!()
233     /// #     }
234     /// # }
235     /// #
236     /// use anyhow::Result;
237     /// use std::fs::File;
238     /// use std::path::Path;
239     ///
240     /// struct ParseError {
241     ///     line: usize,
242     ///     column: usize,
243     /// }
244     ///
245     /// fn parse_impl(file: File) -> Result<T, ParseError> {
246     ///     # const IGNORE: &str = stringify! {
247     ///     ...
248     ///     # };
249     ///     # unimplemented!()
250     /// }
251     ///
252     /// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
253     ///     let file = File::open(&path)?;
254     ///     parse_impl(file).map_err(|error| {
255     ///         let context = format!(
256     ///             "only the first {} lines of {} are valid",
257     ///             error.line, path.as_ref().display(),
258     ///         );
259     ///         anyhow::Error::new(error).context(context)
260     ///     })
261     /// }
262     /// ```
context<C>(self, context: C) -> Self where C: Display + Send + Sync + 'static,263     pub fn context<C>(self, context: C) -> Self
264     where
265         C: Display + Send + Sync + 'static,
266     {
267         let error: ContextError<C, Error> = ContextError {
268             context,
269             error: self,
270         };
271 
272         let vtable = &ErrorVTable {
273             object_drop: object_drop::<ContextError<C, Error>>,
274             object_ref: object_ref::<ContextError<C, Error>>,
275             #[cfg(feature = "std")]
276             object_mut: object_mut::<ContextError<C, Error>>,
277             object_boxed: object_boxed::<ContextError<C, Error>>,
278             object_downcast: context_chain_downcast::<C>,
279             object_drop_rest: context_chain_drop_rest::<C>,
280         };
281 
282         // As the cause is anyhow::Error, we already have a backtrace for it.
283         let backtrace = None;
284 
285         // Safety: passing vtable that operates on the right type.
286         unsafe { Error::construct(error, vtable, backtrace) }
287     }
288 
289     /// Get the backtrace for this Error.
290     ///
291     /// Backtraces are only available on the nightly channel. Tracking issue:
292     /// [rust-lang/rust#53487][tracking].
293     ///
294     /// In order for the backtrace to be meaningful, one of the two environment
295     /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
296     /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
297     /// expensive to capture in Rust, so we don't necessarily want to be
298     /// capturing them all over the place all the time.
299     ///
300     /// - If you want panics and errors to both have backtraces, set
301     ///   `RUST_BACKTRACE=1`;
302     /// - If you want only errors to have backtraces, set
303     ///   `RUST_LIB_BACKTRACE=1`;
304     /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
305     ///   `RUST_LIB_BACKTRACE=0`.
306     ///
307     /// [tracking]: https://github.com/rust-lang/rust/issues/53487
308     #[cfg(backtrace)]
backtrace(&self) -> &Backtrace309     pub fn backtrace(&self) -> &Backtrace {
310         self.inner.backtrace()
311     }
312 
313     /// An iterator of the chain of source errors contained by this Error.
314     ///
315     /// This iterator will visit every error in the cause chain of this error
316     /// object, beginning with the error that this error object was created
317     /// from.
318     ///
319     /// # Example
320     ///
321     /// ```
322     /// use anyhow::Error;
323     /// use std::io;
324     ///
325     /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
326     ///     for cause in error.chain() {
327     ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
328     ///             return Some(io_error.kind());
329     ///         }
330     ///     }
331     ///     None
332     /// }
333     /// ```
334     #[cfg(feature = "std")]
chain(&self) -> Chain335     pub fn chain(&self) -> Chain {
336         self.inner.chain()
337     }
338 
339     /// The lowest level cause of this error &mdash; this error's cause's
340     /// cause's cause etc.
341     ///
342     /// The root cause is the last error in the iterator produced by
343     /// [`chain()`][Error::chain].
344     #[cfg(feature = "std")]
root_cause(&self) -> &(dyn StdError + 'static)345     pub fn root_cause(&self) -> &(dyn StdError + 'static) {
346         let mut chain = self.chain();
347         let mut root_cause = chain.next().unwrap();
348         for cause in chain {
349             root_cause = cause;
350         }
351         root_cause
352     }
353 
354     /// Returns true if `E` is the type held by this error object.
355     ///
356     /// For errors with context, this method returns true if `E` matches the
357     /// type of the context `C` **or** the type of the error on which the
358     /// context has been attached. For details about the interaction between
359     /// context and downcasting, [see here].
360     ///
361     /// [see here]: trait.Context.html#effect-on-downcasting
is<E>(&self) -> bool where E: Display + Debug + Send + Sync + 'static,362     pub fn is<E>(&self) -> bool
363     where
364         E: Display + Debug + Send + Sync + 'static,
365     {
366         self.downcast_ref::<E>().is_some()
367     }
368 
369     /// Attempt to downcast the error object to a concrete type.
downcast<E>(self) -> Result<E, Self> where E: Display + Debug + Send + Sync + 'static,370     pub fn downcast<E>(self) -> Result<E, Self>
371     where
372         E: Display + Debug + Send + Sync + 'static,
373     {
374         let target = TypeId::of::<E>();
375         unsafe {
376             // Use vtable to find NonNull<()> which points to a value of type E
377             // somewhere inside the data structure.
378             let addr = match (self.inner.vtable.object_downcast)(&self.inner, target) {
379                 Some(addr) => addr,
380                 None => return Err(self),
381             };
382 
383             // Prepare to read E out of the data structure. We'll drop the rest
384             // of the data structure separately so that E is not dropped.
385             let outer = ManuallyDrop::new(self);
386 
387             // Read E from where the vtable found it.
388             let error = ptr::read(addr.cast::<E>().as_ptr());
389 
390             // Read Box<ErrorImpl<()>> from self. Can't move it out because
391             // Error has a Drop impl which we want to not run.
392             let inner = ptr::read(&outer.inner);
393             let erased = ManuallyDrop::into_inner(inner);
394 
395             // Drop rest of the data structure outside of E.
396             (erased.vtable.object_drop_rest)(erased, target);
397 
398             Ok(error)
399         }
400     }
401 
402     /// Downcast this error object by reference.
403     ///
404     /// # Example
405     ///
406     /// ```
407     /// # use anyhow::anyhow;
408     /// # use std::fmt::{self, Display};
409     /// # use std::task::Poll;
410     /// #
411     /// # #[derive(Debug)]
412     /// # enum DataStoreError {
413     /// #     Censored(()),
414     /// # }
415     /// #
416     /// # impl Display for DataStoreError {
417     /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
418     /// #         unimplemented!()
419     /// #     }
420     /// # }
421     /// #
422     /// # impl std::error::Error for DataStoreError {}
423     /// #
424     /// # const REDACTED_CONTENT: () = ();
425     /// #
426     /// # let error = anyhow!("...");
427     /// # let root_cause = &error;
428     /// #
429     /// # let ret =
430     /// // If the error was caused by redaction, then return a tombstone instead
431     /// // of the content.
432     /// match root_cause.downcast_ref::<DataStoreError>() {
433     ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
434     ///     None => Err(error),
435     /// }
436     /// # ;
437     /// ```
downcast_ref<E>(&self) -> Option<&E> where E: Display + Debug + Send + Sync + 'static,438     pub fn downcast_ref<E>(&self) -> Option<&E>
439     where
440         E: Display + Debug + Send + Sync + 'static,
441     {
442         let target = TypeId::of::<E>();
443         unsafe {
444             // Use vtable to find NonNull<()> which points to a value of type E
445             // somewhere inside the data structure.
446             let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?;
447             Some(&*addr.cast::<E>().as_ptr())
448         }
449     }
450 
451     /// Downcast this error object by mutable reference.
downcast_mut<E>(&mut self) -> Option<&mut E> where E: Display + Debug + Send + Sync + 'static,452     pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
453     where
454         E: Display + Debug + Send + Sync + 'static,
455     {
456         let target = TypeId::of::<E>();
457         unsafe {
458             // Use vtable to find NonNull<()> which points to a value of type E
459             // somewhere inside the data structure.
460             let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?;
461             Some(&mut *addr.cast::<E>().as_ptr())
462         }
463     }
464 }
465 
466 #[cfg(feature = "std")]
467 impl<E> From<E> for Error
468 where
469     E: StdError + Send + Sync + 'static,
470 {
from(error: E) -> Self471     fn from(error: E) -> Self {
472         let backtrace = backtrace_if_absent!(error);
473         Error::from_std(error, backtrace)
474     }
475 }
476 
477 #[cfg(feature = "std")]
478 impl Deref for Error {
479     type Target = dyn StdError + Send + Sync + 'static;
480 
deref(&self) -> &Self::Target481     fn deref(&self) -> &Self::Target {
482         self.inner.error()
483     }
484 }
485 
486 #[cfg(feature = "std")]
487 impl DerefMut for Error {
deref_mut(&mut self) -> &mut Self::Target488     fn deref_mut(&mut self) -> &mut Self::Target {
489         self.inner.error_mut()
490     }
491 }
492 
493 impl Display for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result494     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
495         self.inner.display(formatter)
496     }
497 }
498 
499 impl Debug for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result500     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
501         self.inner.debug(formatter)
502     }
503 }
504 
505 impl Drop for Error {
drop(&mut self)506     fn drop(&mut self) {
507         unsafe {
508             // Read Box<ErrorImpl<()>> from self.
509             let inner = ptr::read(&self.inner);
510             let erased = ManuallyDrop::into_inner(inner);
511 
512             // Invoke the vtable's drop behavior.
513             (erased.vtable.object_drop)(erased);
514         }
515     }
516 }
517 
518 struct ErrorVTable {
519     object_drop: unsafe fn(Box<ErrorImpl<()>>),
520     object_ref: unsafe fn(&ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static),
521     #[cfg(feature = "std")]
522     object_mut: unsafe fn(&mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static),
523     object_boxed: unsafe fn(Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>,
524     object_downcast: unsafe fn(&ErrorImpl<()>, TypeId) -> Option<NonNull<()>>,
525     object_drop_rest: unsafe fn(Box<ErrorImpl<()>>, TypeId),
526 }
527 
528 // Safety: requires layout of *e to match ErrorImpl<E>.
object_drop<E>(e: Box<ErrorImpl<()>>)529 unsafe fn object_drop<E>(e: Box<ErrorImpl<()>>) {
530     // Cast back to ErrorImpl<E> so that the allocator receives the correct
531     // Layout to deallocate the Box's memory.
532     let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e);
533     drop(unerased);
534 }
535 
536 // Safety: requires layout of *e to match ErrorImpl<E>.
object_drop_front<E>(e: Box<ErrorImpl<()>>, target: TypeId)537 unsafe fn object_drop_front<E>(e: Box<ErrorImpl<()>>, target: TypeId) {
538     // Drop the fields of ErrorImpl other than E as well as the Box allocation,
539     // without dropping E itself. This is used by downcast after doing a
540     // ptr::read to take ownership of the E.
541     let _ = target;
542     let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<ManuallyDrop<E>>>>(e);
543     drop(unerased);
544 }
545 
546 // Safety: requires layout of *e to match ErrorImpl<E>.
object_ref<E>(e: &ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static) where E: StdError + Send + Sync + 'static,547 unsafe fn object_ref<E>(e: &ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static)
548 where
549     E: StdError + Send + Sync + 'static,
550 {
551     // Attach E's native StdError vtable onto a pointer to self._object.
552     &(*(e as *const ErrorImpl<()> as *const ErrorImpl<E>))._object
553 }
554 
555 // Safety: requires layout of *e to match ErrorImpl<E>.
556 #[cfg(feature = "std")]
object_mut<E>(e: &mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static) where E: StdError + Send + Sync + 'static,557 unsafe fn object_mut<E>(e: &mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static)
558 where
559     E: StdError + Send + Sync + 'static,
560 {
561     // Attach E's native StdError vtable onto a pointer to self._object.
562     &mut (*(e as *mut ErrorImpl<()> as *mut ErrorImpl<E>))._object
563 }
564 
565 // Safety: requires layout of *e to match ErrorImpl<E>.
object_boxed<E>(e: Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static> where E: StdError + Send + Sync + 'static,566 unsafe fn object_boxed<E>(e: Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>
567 where
568     E: StdError + Send + Sync + 'static,
569 {
570     // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
571     mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e)
572 }
573 
574 // Safety: requires layout of *e to match ErrorImpl<E>.
object_downcast<E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where E: 'static,575 unsafe fn object_downcast<E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
576 where
577     E: 'static,
578 {
579     if TypeId::of::<E>() == target {
580         // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
581         // pointer to its E field.
582         let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<E>;
583         let addr = &(*unerased)._object as *const E as *mut ();
584         Some(NonNull::new_unchecked(addr))
585     } else {
586         None
587     }
588 }
589 
590 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
591 #[cfg(feature = "std")]
context_downcast<C, E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where C: 'static, E: 'static,592 unsafe fn context_downcast<C, E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
593 where
594     C: 'static,
595     E: 'static,
596 {
597     if TypeId::of::<C>() == target {
598         let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>;
599         let addr = &(*unerased)._object.context as *const C as *mut ();
600         Some(NonNull::new_unchecked(addr))
601     } else if TypeId::of::<E>() == target {
602         let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>;
603         let addr = &(*unerased)._object.error as *const E as *mut ();
604         Some(NonNull::new_unchecked(addr))
605     } else {
606         None
607     }
608 }
609 
610 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
611 #[cfg(feature = "std")]
context_drop_rest<C, E>(e: Box<ErrorImpl<()>>, target: TypeId) where C: 'static, E: 'static,612 unsafe fn context_drop_rest<C, E>(e: Box<ErrorImpl<()>>, target: TypeId)
613 where
614     C: 'static,
615     E: 'static,
616 {
617     // Called after downcasting by value to either the C or the E and doing a
618     // ptr::read to take ownership of that value.
619     if TypeId::of::<C>() == target {
620         let unerased = mem::transmute::<
621             Box<ErrorImpl<()>>,
622             Box<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>,
623         >(e);
624         drop(unerased);
625     } else {
626         let unerased = mem::transmute::<
627             Box<ErrorImpl<()>>,
628             Box<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>,
629         >(e);
630         drop(unerased);
631     }
632 }
633 
634 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> where C: 'static,635 unsafe fn context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>>
636 where
637     C: 'static,
638 {
639     if TypeId::of::<C>() == target {
640         let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
641         let addr = &(*unerased)._object.context as *const C as *mut ();
642         Some(NonNull::new_unchecked(addr))
643     } else {
644         // Recurse down the context chain per the inner error's vtable.
645         let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>;
646         let source = &(*unerased)._object.error;
647         (source.inner.vtable.object_downcast)(&source.inner, target)
648     }
649 }
650 
651 // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId) where C: 'static,652 unsafe fn context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId)
653 where
654     C: 'static,
655 {
656     // Called after downcasting by value to either the C or one of the causes
657     // and doing a ptr::read to take ownership of that value.
658     if TypeId::of::<C>() == target {
659         let unerased = mem::transmute::<
660             Box<ErrorImpl<()>>,
661             Box<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>,
662         >(e);
663         // Drop the entire rest of the data structure rooted in the next Error.
664         drop(unerased);
665     } else {
666         let unerased = mem::transmute::<
667             Box<ErrorImpl<()>>,
668             Box<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>,
669         >(e);
670         // Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
671         let inner = ptr::read(&unerased._object.error.inner);
672         drop(unerased);
673         let erased = ManuallyDrop::into_inner(inner);
674         // Recursively drop the next error using the same target typeid.
675         (erased.vtable.object_drop_rest)(erased, target);
676     }
677 }
678 
679 // repr C to ensure that E remains in the final position.
680 #[repr(C)]
681 pub(crate) struct ErrorImpl<E> {
682     vtable: &'static ErrorVTable,
683     backtrace: Option<Backtrace>,
684     // NOTE: Don't use directly. Use only through vtable. Erased type may have
685     // different alignment.
686     _object: E,
687 }
688 
689 // repr C to ensure that ContextError<C, E> has the same layout as
690 // ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
691 #[repr(C)]
692 pub(crate) struct ContextError<C, E> {
693     pub context: C,
694     pub error: E,
695 }
696 
697 impl<E> ErrorImpl<E> {
erase(&self) -> &ErrorImpl<()>698     fn erase(&self) -> &ErrorImpl<()> {
699         // Erase the concrete type of E but preserve the vtable in self.vtable
700         // for manipulating the resulting thin pointer. This is analogous to an
701         // unsize coersion.
702         unsafe { &*(self as *const ErrorImpl<E> as *const ErrorImpl<()>) }
703     }
704 }
705 
706 impl ErrorImpl<()> {
error(&self) -> &(dyn StdError + Send + Sync + 'static)707     pub(crate) fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
708         // Use vtable to attach E's native StdError vtable for the right
709         // original type E.
710         unsafe { &*(self.vtable.object_ref)(self) }
711     }
712 
713     #[cfg(feature = "std")]
error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static)714     pub(crate) fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
715         // Use vtable to attach E's native StdError vtable for the right
716         // original type E.
717         unsafe { &mut *(self.vtable.object_mut)(self) }
718     }
719 
720     #[cfg(backtrace)]
backtrace(&self) -> &Backtrace721     pub(crate) fn backtrace(&self) -> &Backtrace {
722         // This unwrap can only panic if the underlying error's backtrace method
723         // is nondeterministic, which would only happen in maliciously
724         // constructed code.
725         self.backtrace
726             .as_ref()
727             .or_else(|| self.error().backtrace())
728             .expect("backtrace capture failed")
729     }
730 
chain(&self) -> Chain731     pub(crate) fn chain(&self) -> Chain {
732         Chain::new(self.error())
733     }
734 }
735 
736 impl<E> StdError for ErrorImpl<E>
737 where
738     E: StdError,
739 {
740     #[cfg(backtrace)]
backtrace(&self) -> Option<&Backtrace>741     fn backtrace(&self) -> Option<&Backtrace> {
742         Some(self.erase().backtrace())
743     }
744 
source(&self) -> Option<&(dyn StdError + 'static)>745     fn source(&self) -> Option<&(dyn StdError + 'static)> {
746         self.erase().error().source()
747     }
748 }
749 
750 impl<E> Debug for ErrorImpl<E>
751 where
752     E: Debug,
753 {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result754     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
755         self.erase().debug(formatter)
756     }
757 }
758 
759 impl<E> Display for ErrorImpl<E>
760 where
761     E: Display,
762 {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result763     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
764         Display::fmt(&self.erase().error(), formatter)
765     }
766 }
767 
768 impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
from(error: Error) -> Self769     fn from(error: Error) -> Self {
770         let outer = ManuallyDrop::new(error);
771         unsafe {
772             // Read Box<ErrorImpl<()>> from error. Can't move it out because
773             // Error has a Drop impl which we want to not run.
774             let inner = ptr::read(&outer.inner);
775             let erased = ManuallyDrop::into_inner(inner);
776 
777             // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
778             // the right original type E.
779             (erased.vtable.object_boxed)(erased)
780         }
781     }
782 }
783 
784 impl From<Error> for Box<dyn StdError + 'static> {
from(error: Error) -> Self785     fn from(error: Error) -> Self {
786         Box::<dyn StdError + Send + Sync>::from(error)
787     }
788 }
789 
790 #[cfg(feature = "std")]
791 impl AsRef<dyn StdError + Send + Sync> for Error {
as_ref(&self) -> &(dyn StdError + Send + Sync + 'static)792     fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
793         &**self
794     }
795 }
796 
797 #[cfg(feature = "std")]
798 impl AsRef<dyn StdError> for Error {
as_ref(&self) -> &(dyn StdError + 'static)799     fn as_ref(&self) -> &(dyn StdError + 'static) {
800         &**self
801     }
802 }
803