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 #[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 #[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 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 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 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 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 unsafe { Error::construct(error, vtable, backtrace) }
229 }
230
231 #[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 let inner = Own::new(inner).cast::<ErrorImpl>();
257 Error { inner }
258 }
259
260 #[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 let backtrace = None;
344
345 unsafe { Error::construct(error, vtable, backtrace) }
347 }
348
349 #[cfg(any(std_backtrace, feature = "backtrace"))]
377 pub fn backtrace(&self) -> &impl_backtrace!() {
378 unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
379 }
380
381 #[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 #[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 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 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 #[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 let outer = ManuallyDrop::new(self);
459
460 let error = addr.cast::<E>().read();
462
463 (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
465
466 Ok(error)
467 }
468 }
469
470 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 let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
515 Some(addr.cast::<E>().deref())
516 }
517 }
518
519 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 #[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 #[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 = 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(), 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(), formatter) }
597 }
598}
599
600impl Drop for Error {
601 fn drop(&mut self) {
602 unsafe {
603 (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
626unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
628 let unerased_own = e.cast::<ErrorImpl<E>>();
631 drop(unsafe { unerased_own.boxed() });
632}
633
634unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
636 let _ = target;
640 let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
641 drop(unsafe { unerased_own.boxed() });
642}
643
644unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
646where
647 E: StdError + Send + Sync + 'static,
648{
649 let unerased_ref = e.cast::<ErrorImpl<E>>();
652
653 #[cfg(not(anyhow_no_ptr_addr_of))]
654 return Ref::from_raw(unsafe {
655 NonNull::new_unchecked(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#[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 let unerased_mut = e.cast::<ErrorImpl<E>>();
671 unsafe { &mut unerased_mut.deref_mut()._object }
672}
673
674unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
676where
677 E: StdError + Send + Sync + 'static,
678{
679 let unerased_own = e.cast::<ErrorImpl<E>>();
681 unsafe { unerased_own.boxed() }
682}
683
684unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
686where
687 E: 'static,
688{
689 if TypeId::of::<E>() == target {
690 let unerased_ref = e.cast::<ErrorImpl<E>>();
694
695 #[cfg(not(anyhow_no_ptr_addr_of))]
696 return Some(
697 Ref::from_raw(unsafe {
698 NonNull::new_unchecked(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#[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 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#[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 = e.cast::<ErrorImpl<ContextError<C, E>>>();
745 let unerased = unsafe { unerased_ref.deref() };
746 Some(Ref::new(&unerased._object.context).cast::<()>())
747 } else if TypeId::of::<E>() == target {
748 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
749 let unerased = unsafe { unerased_ref.deref() };
750 Some(Ref::new(&unerased._object.error).cast::<()>())
751 } else {
752 None
753 }
754}
755
756#[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#[cfg(feature = "std")]
778unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
779where
780 C: 'static,
781 E: 'static,
782{
783 if TypeId::of::<C>() == target {
786 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
787 drop(unsafe { unerased_own.boxed() });
788 } else {
789 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
790 drop(unsafe { unerased_own.boxed() });
791 }
792}
793
794unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
796where
797 C: 'static,
798{
799 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
800 let unerased = unsafe { unerased_ref.deref() };
801 if TypeId::of::<C>() == target {
802 Some(Ref::new(&unerased._object.context).cast::<()>())
803 } else {
804 let source = &unerased._object.error;
806 unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
807 }
808}
809
810#[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 let source = &mut unerased._object.error;
823 unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) }
824 }
825}
826
827unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
829where
830 C: 'static,
831{
832 if TypeId::of::<C>() == target {
835 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
836 drop(unsafe { unerased_own.boxed() });
838 } else {
839 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
840 let unerased = unsafe { unerased_own.boxed() };
841 let inner = unerased._object.error.inner;
843 drop(unerased);
844 let vtable = unsafe { vtable(inner.ptr) };
845 unsafe { (vtable.object_drop_rest)(inner, target) };
847 }
848}
849
850#[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#[repr(C)]
870pub(crate) struct ErrorImpl<E = ()> {
871 vtable: &'static ErrorVTable,
872 backtrace: Option<Backtrace>,
873 _object: E,
876}
877
878unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
881 unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
883}
884
885#[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 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 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 #[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 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(), 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(ErrorImpl::error(self.erase()), 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::new(error);
992 unsafe {
993 (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}