anyhow/
error.rs

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