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 #[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 #[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 #[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 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 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 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 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 unsafe { Error::construct(error, vtable, backtrace) }
296 }
297
298 #[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 let inner = Own::new(inner).cast::<ErrorImpl>();
324 Error { inner }
325 }
326
327 #[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 let backtrace = None;
411
412 unsafe { Error::construct(error, vtable, backtrace) }
414 }
415
416 #[cfg(any(std_backtrace, feature = "backtrace"))]
444 pub fn backtrace(&self) -> &impl_backtrace!() {
445 unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
446 }
447
448 #[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 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
481 #[allow(clippy::double_ended_iterator_last)]
482 pub fn root_cause(&self) -> &(dyn StdError + 'static) {
483 self.chain().last().unwrap()
484 }
485
486 pub fn is<E>(&self) -> bool
495 where
496 E: Display + Debug + Send + Sync + 'static,
497 {
498 self.downcast_ref::<E>().is_some()
499 }
500
501 pub fn downcast<E>(mut self) -> Result<E, Self>
503 where
504 E: Display + Debug + Send + Sync + 'static,
505 {
506 let target = TypeId::of::<E>();
507 let inner = self.inner.by_mut();
508 unsafe {
509 #[cfg(not(anyhow_no_ptr_addr_of))]
512 let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
513 Some(addr) => addr.by_mut().extend(),
514 None => return Err(self),
515 };
516 #[cfg(anyhow_no_ptr_addr_of)]
517 let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) {
518 Some(addr) => addr.extend(),
519 None => return Err(self),
520 };
521
522 let outer = ManuallyDrop::new(self);
525
526 let error = addr.cast::<E>().read();
528
529 (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
531
532 Ok(error)
533 }
534 }
535
536 pub fn downcast_ref<E>(&self) -> Option<&E>
573 where
574 E: Display + Debug + Send + Sync + 'static,
575 {
576 let target = TypeId::of::<E>();
577 unsafe {
578 let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
581 Some(addr.cast::<E>().deref())
582 }
583 }
584
585 pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
587 where
588 E: Display + Debug + Send + Sync + 'static,
589 {
590 let target = TypeId::of::<E>();
591 unsafe {
592 #[cfg(not(anyhow_no_ptr_addr_of))]
596 let addr =
597 (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
598
599 #[cfg(anyhow_no_ptr_addr_of)]
600 let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?;
601
602 Some(addr.cast::<E>().deref_mut())
603 }
604 }
605
606 #[cfg(error_generic_member_access)]
607 pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
608 unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
609 }
610
611 #[cfg(error_generic_member_access)]
617 #[doc(hidden)]
618 pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
619 Self::provide(self, request);
620 }
621}
622
623#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
624impl<E> From<E> for Error
625where
626 E: StdError + Send + Sync + 'static,
627{
628 #[cold]
629 fn from(error: E) -> Self {
630 let backtrace = backtrace_if_absent!(&error);
631 Error::construct_from_std(error, backtrace)
632 }
633}
634
635#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
636impl Deref for Error {
637 type Target = dyn StdError + Send + Sync + 'static;
638
639 fn deref(&self) -> &Self::Target {
640 unsafe { ErrorImpl::error(self.inner.by_ref()) }
641 }
642}
643
644#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
645impl DerefMut for Error {
646 fn deref_mut(&mut self) -> &mut Self::Target {
647 unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
648 }
649}
650
651impl Display for Error {
652 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
653 unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
654 }
655}
656
657impl Debug for Error {
658 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
659 unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
660 }
661}
662
663impl Drop for Error {
664 fn drop(&mut self) {
665 unsafe {
666 (vtable(self.inner.ptr).object_drop)(self.inner);
668 }
669 }
670}
671
672struct ErrorVTable {
673 object_drop: unsafe fn(Own<ErrorImpl>),
674 object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
675 #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))]
676 object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
677 object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
678 object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
679 #[cfg(anyhow_no_ptr_addr_of)]
680 object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>,
681 object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
682 #[cfg(all(
683 not(error_generic_member_access),
684 any(std_backtrace, feature = "backtrace")
685 ))]
686 object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
687}
688
689unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
691 let unerased_own = e.cast::<ErrorImpl<E>>();
694 drop(unsafe { unerased_own.boxed() });
695}
696
697unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
699 let _ = target;
703 let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
704 drop(unsafe { unerased_own.boxed() });
705}
706
707unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
709where
710 E: StdError + Send + Sync + 'static,
711{
712 let unerased_ref = e.cast::<ErrorImpl<E>>();
715
716 #[cfg(not(anyhow_no_ptr_addr_of))]
717 return Ref::from_raw(unsafe {
718 NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
719 });
720
721 #[cfg(anyhow_no_ptr_addr_of)]
722 return Ref::new(unsafe { &unerased_ref.deref()._object });
723}
724
725#[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))]
728unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
729where
730 E: StdError + Send + Sync + 'static,
731{
732 let unerased_mut = e.cast::<ErrorImpl<E>>();
734 unsafe { &mut unerased_mut.deref_mut()._object }
735}
736
737unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
739where
740 E: StdError + Send + Sync + 'static,
741{
742 let unerased_own = e.cast::<ErrorImpl<E>>();
744 unsafe { unerased_own.boxed() }
745}
746
747unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
749where
750 E: 'static,
751{
752 if TypeId::of::<E>() == target {
753 let unerased_ref = e.cast::<ErrorImpl<E>>();
757
758 #[cfg(not(anyhow_no_ptr_addr_of))]
759 return Some(
760 Ref::from_raw(unsafe {
761 NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
762 })
763 .cast::<()>(),
764 );
765
766 #[cfg(anyhow_no_ptr_addr_of)]
767 return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>());
768 } else {
769 None
770 }
771}
772
773#[cfg(anyhow_no_ptr_addr_of)]
775unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
776where
777 E: 'static,
778{
779 if TypeId::of::<E>() == target {
780 let unerased_mut = e.cast::<ErrorImpl<E>>();
783 let unerased = unsafe { unerased_mut.deref_mut() };
784 Some(Mut::new(&mut unerased._object).cast::<()>())
785 } else {
786 None
787 }
788}
789
790#[cfg(all(
791 not(error_generic_member_access),
792 any(std_backtrace, feature = "backtrace")
793))]
794fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
795 let _ = e;
796 None
797}
798
799#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
801unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
802where
803 C: 'static,
804 E: 'static,
805{
806 if TypeId::of::<C>() == target {
807 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
808 let unerased = unsafe { unerased_ref.deref() };
809 Some(Ref::new(&unerased._object.context).cast::<()>())
810 } else if TypeId::of::<E>() == target {
811 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
812 let unerased = unsafe { unerased_ref.deref() };
813 Some(Ref::new(&unerased._object.error).cast::<()>())
814 } else {
815 None
816 }
817}
818
819#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
821unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
822where
823 C: 'static,
824 E: 'static,
825{
826 if TypeId::of::<C>() == target {
827 let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
828 let unerased = unsafe { unerased_mut.deref_mut() };
829 Some(Mut::new(&mut unerased._object.context).cast::<()>())
830 } else if TypeId::of::<E>() == target {
831 let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
832 let unerased = unsafe { unerased_mut.deref_mut() };
833 Some(Mut::new(&mut unerased._object.error).cast::<()>())
834 } else {
835 None
836 }
837}
838
839#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
841unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
842where
843 C: 'static,
844 E: 'static,
845{
846 if TypeId::of::<C>() == target {
849 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
850 drop(unsafe { unerased_own.boxed() });
851 } else {
852 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
853 drop(unsafe { unerased_own.boxed() });
854 }
855}
856
857unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
859where
860 C: 'static,
861{
862 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
863 let unerased = unsafe { unerased_ref.deref() };
864 if TypeId::of::<C>() == target {
865 Some(Ref::new(&unerased._object.context).cast::<()>())
866 } else {
867 let source = &unerased._object.error;
869 unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
870 }
871}
872
873#[cfg(anyhow_no_ptr_addr_of)]
875unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
876where
877 C: 'static,
878{
879 let unerased_mut = e.cast::<ErrorImpl<ContextError<C, Error>>>();
880 let unerased = unsafe { unerased_mut.deref_mut() };
881 if TypeId::of::<C>() == target {
882 Some(Mut::new(&mut unerased._object.context).cast::<()>())
883 } else {
884 let source = &mut unerased._object.error;
886 unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) }
887 }
888}
889
890unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
892where
893 C: 'static,
894{
895 if TypeId::of::<C>() == target {
898 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
899 drop(unsafe { unerased_own.boxed() });
901 } else {
902 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
903 let unerased = unsafe { unerased_own.boxed() };
904 let inner = unerased._object.error.inner;
906 drop(unerased);
907 let vtable = unsafe { vtable(inner.ptr) };
908 unsafe { (vtable.object_drop_rest)(inner, target) };
910 }
911}
912
913#[cfg(all(
915 not(error_generic_member_access),
916 any(std_backtrace, feature = "backtrace")
917))]
918#[allow(clippy::unnecessary_wraps)]
919unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
920where
921 C: 'static,
922{
923 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
924 let unerased = unsafe { unerased_ref.deref() };
925 let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) };
926 Some(backtrace)
927}
928
929#[repr(C)]
933pub(crate) struct ErrorImpl<E = ()> {
934 vtable: &'static ErrorVTable,
935 backtrace: Option<Backtrace>,
936 _object: E,
939}
940
941unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
944 unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
946}
947
948#[repr(C)]
951pub(crate) struct ContextError<C, E> {
952 pub context: C,
953 pub error: E,
954}
955
956impl<E> ErrorImpl<E> {
957 fn erase(&self) -> Ref<ErrorImpl> {
958 Ref::new(self).cast::<ErrorImpl>()
962 }
963}
964
965impl ErrorImpl {
966 pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
967 unsafe { (vtable(this.ptr).object_ref)(this).deref() }
970 }
971
972 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
973 pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
974 #[cfg(not(anyhow_no_ptr_addr_of))]
978 return unsafe {
979 (vtable(this.ptr).object_ref)(this.by_ref())
980 .by_mut()
981 .deref_mut()
982 };
983
984 #[cfg(anyhow_no_ptr_addr_of)]
985 return unsafe { (vtable(this.ptr).object_mut)(this) };
986 }
987
988 #[cfg(any(std_backtrace, feature = "backtrace"))]
989 pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
990 unsafe { this.deref() }
994 .backtrace
995 .as_ref()
996 .or_else(|| {
997 #[cfg(error_generic_member_access)]
998 return error::request_ref::<Backtrace>(unsafe { Self::error(this) });
999 #[cfg(not(error_generic_member_access))]
1000 return unsafe { (vtable(this.ptr).object_backtrace)(this) };
1001 })
1002 .expect("backtrace capture failed")
1003 }
1004
1005 #[cfg(error_generic_member_access)]
1006 unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
1007 if let Some(backtrace) = unsafe { &this.deref().backtrace } {
1008 request.provide_ref(backtrace);
1009 }
1010 unsafe { Self::error(this) }.provide(request);
1011 }
1012
1013 #[cold]
1014 pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
1015 Chain::new(unsafe { Self::error(this) })
1016 }
1017}
1018
1019impl<E> StdError for ErrorImpl<E>
1020where
1021 E: StdError,
1022{
1023 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1024 unsafe { ErrorImpl::error(self.erase()).source() }
1025 }
1026
1027 #[cfg(error_generic_member_access)]
1028 fn provide<'a>(&'a self, request: &mut Request<'a>) {
1029 unsafe { ErrorImpl::provide(self.erase(), request) }
1030 }
1031}
1032
1033impl<E> Debug for ErrorImpl<E>
1034where
1035 E: Debug,
1036{
1037 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1038 unsafe { ErrorImpl::debug(self.erase(), formatter) }
1039 }
1040}
1041
1042impl<E> Display for ErrorImpl<E>
1043where
1044 E: Display,
1045{
1046 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1047 unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
1048 }
1049}
1050
1051impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
1052 #[cold]
1053 fn from(error: Error) -> Self {
1054 let outer = ManuallyDrop::new(error);
1055 unsafe {
1056 (vtable(outer.inner.ptr).object_boxed)(outer.inner)
1059 }
1060 }
1061}
1062
1063impl From<Error> for Box<dyn StdError + Send + 'static> {
1064 fn from(error: Error) -> Self {
1065 Box::<dyn StdError + Send + Sync>::from(error)
1066 }
1067}
1068
1069impl From<Error> for Box<dyn StdError + 'static> {
1070 fn from(error: Error) -> Self {
1071 Box::<dyn StdError + Send + Sync>::from(error)
1072 }
1073}
1074
1075#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1076impl AsRef<dyn StdError + Send + Sync> for Error {
1077 fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
1078 &**self
1079 }
1080}
1081
1082#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1083impl AsRef<dyn StdError> for Error {
1084 fn as_ref(&self) -> &(dyn StdError + 'static) {
1085 &**self
1086 }
1087}
1088
1089#[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))]
1090impl UnwindSafe for Error {}
1091
1092#[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))]
1093impl RefUnwindSafe for Error {}