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 pub fn root_cause(&self) -> &(dyn StdError + 'static) {
482 self.chain().last().unwrap()
483 }
484
485 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 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 #[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 let outer = ManuallyDrop::new(self);
524
525 let error = addr.cast::<E>().read();
527
528 (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
530
531 Ok(error)
532 }
533 }
534
535 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 let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
580 Some(addr.cast::<E>().deref())
581 }
582 }
583
584 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 #[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 #[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 = 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(), 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(), formatter) }
659 }
660}
661
662impl Drop for Error {
663 fn drop(&mut self) {
664 unsafe {
665 (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
688unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
690 let unerased_own = e.cast::<ErrorImpl<E>>();
693 drop(unsafe { unerased_own.boxed() });
694}
695
696unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
698 let _ = target;
702 let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
703 drop(unsafe { unerased_own.boxed() });
704}
705
706unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
708where
709 E: StdError + Send + Sync + 'static,
710{
711 let unerased_ref = e.cast::<ErrorImpl<E>>();
714
715 #[cfg(not(anyhow_no_ptr_addr_of))]
716 return Ref::from_raw(unsafe {
717 NonNull::new_unchecked(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#[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 let unerased_mut = e.cast::<ErrorImpl<E>>();
733 unsafe { &mut unerased_mut.deref_mut()._object }
734}
735
736unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
738where
739 E: StdError + Send + Sync + 'static,
740{
741 let unerased_own = e.cast::<ErrorImpl<E>>();
743 unsafe { unerased_own.boxed() }
744}
745
746unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
748where
749 E: 'static,
750{
751 if TypeId::of::<E>() == target {
752 let unerased_ref = e.cast::<ErrorImpl<E>>();
756
757 #[cfg(not(anyhow_no_ptr_addr_of))]
758 return Some(
759 Ref::from_raw(unsafe {
760 NonNull::new_unchecked(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#[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 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#[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 = e.cast::<ErrorImpl<ContextError<C, E>>>();
807 let unerased = unsafe { unerased_ref.deref() };
808 Some(Ref::new(&unerased._object.context).cast::<()>())
809 } else if TypeId::of::<E>() == target {
810 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
811 let unerased = unsafe { unerased_ref.deref() };
812 Some(Ref::new(&unerased._object.error).cast::<()>())
813 } else {
814 None
815 }
816}
817
818#[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#[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 if TypeId::of::<C>() == target {
848 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
849 drop(unsafe { unerased_own.boxed() });
850 } else {
851 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
852 drop(unsafe { unerased_own.boxed() });
853 }
854}
855
856unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
858where
859 C: 'static,
860{
861 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
862 let unerased = unsafe { unerased_ref.deref() };
863 if TypeId::of::<C>() == target {
864 Some(Ref::new(&unerased._object.context).cast::<()>())
865 } else {
866 let source = &unerased._object.error;
868 unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
869 }
870}
871
872#[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 let source = &mut unerased._object.error;
885 unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) }
886 }
887}
888
889unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
891where
892 C: 'static,
893{
894 if TypeId::of::<C>() == target {
897 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
898 drop(unsafe { unerased_own.boxed() });
900 } else {
901 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
902 let unerased = unsafe { unerased_own.boxed() };
903 let inner = unerased._object.error.inner;
905 drop(unerased);
906 let vtable = unsafe { vtable(inner.ptr) };
907 unsafe { (vtable.object_drop_rest)(inner, target) };
909 }
910}
911
912#[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#[repr(C)]
932pub(crate) struct ErrorImpl<E = ()> {
933 vtable: &'static ErrorVTable,
934 backtrace: Option<Backtrace>,
935 _object: E,
938}
939
940unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
943 unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
945}
946
947#[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 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 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 #[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 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(), 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(ErrorImpl::error(self.erase()), 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::new(error);
1054 unsafe {
1055 (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 {}