anyhow/
error.rs

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