Skip to main content

anyerr/
error.rs

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