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