1use crate::backtrace::Backtrace;
2use crate::chain::Chain;
3#[cfg(any(feature = "std", anyhow_no_ptr_addr_of))]
4use crate::ptr::Mut;
5use crate::ptr::{Own, Ref};
6use crate::{Error, StdError};
7use alloc::boxed::Box;
8use core::any::TypeId;
9use core::fmt::{self, Debug, Display};
10use core::mem::ManuallyDrop;
11#[cfg(not(anyhow_no_ptr_addr_of))]
12use core::ptr;
13use core::ptr::NonNull;
14#[cfg(backtrace)]
15use std::error::{self, Request};
16
17#[cfg(feature = "std")]
18use core::ops::{Deref, DerefMut};
19
20impl Error {
21 /// Create a new error object from any error type.
22 ///
23 /// The error type must be threadsafe and `'static`, so that the `Error`
24 /// will be as well.
25 ///
26 /// If the error type does not provide a backtrace, a backtrace will be
27 /// created here to ensure that a backtrace exists.
28 #[cfg(feature = "std")]
29 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
30 #[cold]
31 #[must_use]
32 pub fn new<E>(error: E) -> Self
33 where
34 E: StdError + Send + Sync + 'static,
35 {
36 let backtrace = backtrace_if_absent!(&error);
37 Error::from_std(error, backtrace)
38 }
39
40 /// Create a new error object from a printable error message.
41 ///
42 /// If the argument implements std::error::Error, prefer `Error::new`
43 /// instead which preserves the underlying error's cause chain and
44 /// backtrace. If the argument may or may not implement std::error::Error
45 /// now or in the future, use `anyhow!(err)` which handles either way
46 /// correctly.
47 ///
48 /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
49 /// convenient in places where a function is preferable over a macro, such
50 /// as iterator or stream combinators:
51 ///
52 /// ```
53 /// # mod ffi {
54 /// # pub struct Input;
55 /// # pub struct Output;
56 /// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
57 /// # unimplemented!()
58 /// # }
59 /// # }
60 /// #
61 /// # use ffi::{Input, Output};
62 /// #
63 /// use anyhow::{Error, Result};
64 /// use futures::stream::{Stream, StreamExt, TryStreamExt};
65 ///
66 /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
67 /// where
68 /// S: Stream<Item = Input>,
69 /// {
70 /// stream
71 /// .then(ffi::do_some_work) // returns Result<Output, &str>
72 /// .map_err(Error::msg)
73 /// .try_collect()
74 /// .await
75 /// }
76 /// ```
77 #[cold]
78 #[must_use]
79 pub fn msg<M>(message: M) -> Self
80 where
81 M: Display + Debug + Send + Sync + 'static,
82 {
83 Error::from_adhoc(message, backtrace!())
84 }
85
86 #[cfg(feature = "std")]
87 #[cold]
88 pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
89 where
90 E: StdError + Send + Sync + 'static,
91 {
92 let vtable = &ErrorVTable {
93 object_drop: object_drop::<E>,
94 object_ref: object_ref::<E>,
95 #[cfg(anyhow_no_ptr_addr_of)]
96 object_mut: object_mut::<E>,
97 object_boxed: object_boxed::<E>,
98 object_downcast: object_downcast::<E>,
99 #[cfg(anyhow_no_ptr_addr_of)]
100 object_downcast_mut: object_downcast_mut::<E>,
101 object_drop_rest: object_drop_front::<E>,
102 #[cfg(all(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]
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]
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]
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]
191 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]
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]
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"))))]
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]
391 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")))]
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
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.
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 /// ```
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.
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 #[cfg(backtrace)]
527 pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
528 unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
529 }
530
531 // Called by thiserror when you have `#[source] anyhow::Error`. This provide
532 // implementation includes the anyhow::Error's Backtrace if any, unlike
533 // deref'ing to dyn Error where the provide implementation would include
534 // only the original error's Backtrace from before it got wrapped into an
535 // anyhow::Error.
536 #[cfg(backtrace)]
537 #[doc(hidden)]
538 pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
539 Self::provide(self, request);
540 }
541}
542
543#[cfg(feature = "std")]
544#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
545impl<E> From<E> for Error
546where
547 E: StdError + Send + Sync + 'static,
548{
549 #[cold]
550 fn from(error: E) -> Self {
551 let backtrace: Option = backtrace_if_absent!(&error);
552 Error::from_std(error, backtrace)
553 }
554}
555
556#[cfg(feature = "std")]
557#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
558impl Deref for Error {
559 type Target = dyn StdError + Send + Sync + 'static;
560
561 fn deref(&self) -> &Self::Target {
562 unsafe { ErrorImpl::error(self.inner.by_ref()) }
563 }
564}
565
566#[cfg(feature = "std")]
567#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
568impl DerefMut for Error {
569 fn deref_mut(&mut self) -> &mut Self::Target {
570 unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
571 }
572}
573
574impl Display for Error {
575 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
576 unsafe { ErrorImpl::display(self.inner.by_ref(), f:formatter) }
577 }
578}
579
580impl Debug for Error {
581 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
582 unsafe { ErrorImpl::debug(self.inner.by_ref(), f:formatter) }
583 }
584}
585
586impl Drop for Error {
587 fn drop(&mut self) {
588 unsafe {
589 // Invoke the vtable's drop behavior.
590 (vtable(self.inner.ptr).object_drop)(self.inner);
591 }
592 }
593}
594
595struct ErrorVTable {
596 object_drop: unsafe fn(Own<ErrorImpl>),
597 object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
598 #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
599 object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
600 object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
601 object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
602 #[cfg(anyhow_no_ptr_addr_of)]
603 object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>,
604 object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
605 #[cfg(all(not(backtrace), feature = "backtrace"))]
606 object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
607}
608
609// Safety: requires layout of *e to match ErrorImpl<E>.
610unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
611 // Cast back to ErrorImpl<E> so that the allocator receives the correct
612 // Layout to deallocate the Box's memory.
613 let unerased: Box> = e.cast::<ErrorImpl<E>>().boxed();
614 drop(unerased);
615}
616
617// Safety: requires layout of *e to match ErrorImpl<E>.
618unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
619 // Drop the fields of ErrorImpl other than E as well as the Box allocation,
620 // without dropping E itself. This is used by downcast after doing a
621 // ptr::read to take ownership of the E.
622 let _ = target;
623 let unerased: Box>> = e.cast::<ErrorImpl<ManuallyDrop<E>>>().boxed();
624 drop(unerased);
625}
626
627// Safety: requires layout of *e to match ErrorImpl<E>.
628unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
629where
630 E: StdError + Send + Sync + 'static,
631{
632 // Attach E's native StdError vtable onto a pointer to self._object.
633
634 let unerased: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>();
635
636 #[cfg(not(anyhow_no_ptr_addr_of))]
637 return Ref::from_raw(ptr:NonNull::new_unchecked(
638 ptr:ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
639 ));
640
641 #[cfg(anyhow_no_ptr_addr_of)]
642 return Ref::new(&unerased.deref()._object);
643}
644
645// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
646// from a `&mut`
647#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
648unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
649where
650 E: StdError + Send + Sync + 'static,
651{
652 // Attach E's native StdError vtable onto a pointer to self._object.
653 &mut e.cast::<ErrorImpl<E>>().deref_mut()._object
654}
655
656// Safety: requires layout of *e to match ErrorImpl<E>.
657unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
658where
659 E: StdError + Send + Sync + 'static,
660{
661 // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
662 e.cast::<ErrorImpl<E>>().boxed()
663}
664
665// Safety: requires layout of *e to match ErrorImpl<E>.
666unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
667where
668 E: 'static,
669{
670 if TypeId::of::<E>() == target {
671 // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
672 // pointer to its E field.
673
674 let unerased: Ref<'_, ErrorImpl> = e.cast::<ErrorImpl<E>>();
675
676 #[cfg(not(anyhow_no_ptr_addr_of))]
677 return Some(
678 RefRef<'_, E>::from_raw(ptr:NonNull::new_unchecked(
679 ptr:ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
680 ))
681 .cast::<()>(),
682 );
683
684 #[cfg(anyhow_no_ptr_addr_of)]
685 return Some(Ref::new(&unerased.deref()._object).cast::<()>());
686 } else {
687 None
688 }
689}
690
691// Safety: requires layout of *e to match ErrorImpl<E>.
692#[cfg(anyhow_no_ptr_addr_of)]
693unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
694where
695 E: 'static,
696{
697 if TypeId::of::<E>() == target {
698 // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
699 // pointer to its E field.
700 let unerased = e.cast::<ErrorImpl<E>>().deref_mut();
701 Some(Mut::new(&mut unerased._object).cast::<()>())
702 } else {
703 None
704 }
705}
706
707#[cfg(all(not(backtrace), feature = "backtrace"))]
708fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
709 let _ = e;
710 None
711}
712
713// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
714#[cfg(feature = "std")]
715unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
716where
717 C: 'static,
718 E: 'static,
719{
720 if TypeId::of::<C>() == target {
721 let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
722 Some(Ref::new(&unerased._object.context).cast::<()>())
723 } else if TypeId::of::<E>() == target {
724 let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
725 Some(Ref::new(&unerased._object.error).cast::<()>())
726 } else {
727 None
728 }
729}
730
731// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
732#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
733unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
734where
735 C: 'static,
736 E: 'static,
737{
738 if TypeId::of::<C>() == target {
739 let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
740 Some(Mut::new(&mut unerased._object.context).cast::<()>())
741 } else if TypeId::of::<E>() == target {
742 let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
743 Some(Mut::new(&mut unerased._object.error).cast::<()>())
744 } else {
745 None
746 }
747}
748
749// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
750#[cfg(feature = "std")]
751unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
752where
753 C: 'static,
754 E: 'static,
755{
756 // Called after downcasting by value to either the C or the E and doing a
757 // ptr::read to take ownership of that value.
758 if TypeId::of::<C>() == target {
759 let unerased: Box>> = eOwn>>
760 .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>()
761 .boxed();
762 drop(unerased);
763 } else {
764 let unerased: Box>> = eOwn>>
765 .cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>()
766 .boxed();
767 drop(unerased);
768 }
769}
770
771// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
772unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
773where
774 C: 'static,
775{
776 let unerased: &ErrorImpl> = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
777 if TypeId::of::<C>() == target {
778 Some(Ref::new(&unerased._object.context).cast::<()>())
779 } else {
780 // Recurse down the context chain per the inner error's vtable.
781 let source: &Error = &unerased._object.error;
782 (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target)
783 }
784}
785
786// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
787#[cfg(anyhow_no_ptr_addr_of)]
788unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
789where
790 C: 'static,
791{
792 let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref_mut();
793 if TypeId::of::<C>() == target {
794 Some(Mut::new(&mut unerased._object.context).cast::<()>())
795 } else {
796 // Recurse down the context chain per the inner error's vtable.
797 let source = &mut unerased._object.error;
798 (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target)
799 }
800}
801
802// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
803unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
804where
805 C: 'static,
806{
807 // Called after downcasting by value to either the C or one of the causes
808 // and doing a ptr::read to take ownership of that value.
809 if TypeId::of::<C>() == target {
810 let unerased: Box>> = eOwn>>
811 .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>()
812 .boxed();
813 // Drop the entire rest of the data structure rooted in the next Error.
814 drop(unerased);
815 } else {
816 let unerased: Box>> = eOwn>>
817 .cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>()
818 .boxed();
819 // Read the Own<ErrorImpl> from the next error.
820 let inner: Own = unerased._object.error.inner;
821 drop(unerased);
822 let vtable: &ErrorVTable = vtable(inner.ptr);
823 // Recursively drop the next error using the same target typeid.
824 (vtable.object_drop_rest)(inner, target);
825 }
826}
827
828// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
829#[cfg(all(not(backtrace), feature = "backtrace"))]
830#[allow(clippy::unnecessary_wraps)]
831unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
832where
833 C: 'static,
834{
835 let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
836 let backtrace = ErrorImpl::backtrace(unerased._object.error.inner.by_ref());
837 Some(backtrace)
838}
839
840// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
841// of raw pointers and `NonNull`.
842// repr C to ensure that E remains in the final position.
843#[repr(C)]
844pub(crate) struct ErrorImpl<E = ()> {
845 vtable: &'static ErrorVTable,
846 backtrace: Option<Backtrace>,
847 // NOTE: Don't use directly. Use only through vtable. Erased type may have
848 // different alignment.
849 _object: E,
850}
851
852// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
853// avoids converting `p` into a reference.
854unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
855 // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
856 *(p.as_ptr() as *const &'static ErrorVTable)
857}
858
859// repr C to ensure that ContextError<C, E> has the same layout as
860// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
861#[repr(C)]
862pub(crate) struct ContextError<C, E> {
863 pub context: C,
864 pub error: E,
865}
866
867impl<E> ErrorImpl<E> {
868 fn erase(&self) -> Ref<ErrorImpl> {
869 // Erase the concrete type of E but preserve the vtable in self.vtable
870 // for manipulating the resulting thin pointer. This is analogous to an
871 // unsize coercion.
872 Ref::new(self).cast::<ErrorImpl>()
873 }
874}
875
876impl ErrorImpl {
877 pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
878 // Use vtable to attach E's native StdError vtable for the right
879 // original type E.
880 (vtable(this.ptr).object_ref)(this).deref()
881 }
882
883 #[cfg(feature = "std")]
884 pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
885 // Use vtable to attach E's native StdError vtable for the right
886 // original type E.
887
888 #[cfg(not(anyhow_no_ptr_addr_of))]
889 return (vtable(this.ptr).object_ref)(this.by_ref())
890 .by_mut()
891 .deref_mut();
892
893 #[cfg(anyhow_no_ptr_addr_of)]
894 return (vtable(this.ptr).object_mut)(this);
895 }
896
897 #[cfg(any(backtrace, feature = "backtrace"))]
898 pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
899 // This unwrap can only panic if the underlying error's backtrace method
900 // is nondeterministic, which would only happen in maliciously
901 // constructed code.
902 this.deref()
903 .backtrace
904 .as_ref()
905 .or_else(|| {
906 #[cfg(backtrace)]
907 return error::request_ref::<Backtrace>(Self::error(this));
908 #[cfg(not(backtrace))]
909 return (vtable(this.ptr).object_backtrace)(this);
910 })
911 .expect("backtrace capture failed")
912 }
913
914 #[cfg(backtrace)]
915 unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
916 if let Some(backtrace) = &this.deref().backtrace {
917 request.provide_ref(backtrace);
918 }
919 Self::error(this).provide(request);
920 }
921
922 #[cold]
923 pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
924 Chain::new(Self::error(this))
925 }
926}
927
928impl<E> StdError for ErrorImpl<E>
929where
930 E: StdError,
931{
932 fn source(&self) -> Option<&(dyn StdError + 'static)> {
933 unsafe { ErrorImpl::error(self.erase()).source() }
934 }
935
936 #[cfg(backtrace)]
937 fn provide<'a>(&'a self, request: &mut Request<'a>) {
938 unsafe { ErrorImpl::provide(self.erase(), request) }
939 }
940}
941
942impl<E> Debug for ErrorImpl<E>
943where
944 E: Debug,
945{
946 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
947 unsafe { ErrorImpl::debug(self.erase(), f:formatter) }
948 }
949}
950
951impl<E> Display for ErrorImpl<E>
952where
953 E: Display,
954{
955 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
956 unsafe { Display::fmt(self:ErrorImpl::error(self.erase()), f:formatter) }
957 }
958}
959
960impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
961 #[cold]
962 fn from(error: Error) -> Self {
963 let outer: ManuallyDrop = ManuallyDrop::new(error);
964 unsafe {
965 // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
966 // the right original type E.
967 (vtable(outer.inner.ptr).object_boxed)(outer.inner)
968 }
969 }
970}
971
972impl From<Error> for Box<dyn StdError + Send + 'static> {
973 fn from(error: Error) -> Self {
974 Box::<dyn StdError + Send + Sync>::from(error)
975 }
976}
977
978impl From<Error> for Box<dyn StdError + 'static> {
979 fn from(error: Error) -> Self {
980 Box::<dyn StdError + Send + Sync>::from(error)
981 }
982}
983
984#[cfg(feature = "std")]
985impl AsRef<dyn StdError + Send + Sync> for Error {
986 fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
987 &**self
988 }
989}
990
991#[cfg(feature = "std")]
992impl AsRef<dyn StdError> for Error {
993 fn as_ref(&self) -> &(dyn StdError + 'static) {
994 &**self
995 }
996}
997