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