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