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