anyhow/
error.rs

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