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