11use crate :: alloc:: Box ;
22use crate :: backtrace:: Backtrace ;
33use crate :: chain:: Chain ;
4- use crate :: ptr:: { Mut , Own , Ref } ;
4+ #[ cfg( any( feature = "std" , anyhow_no_ptr_addr_of) ) ]
5+ use crate :: ptr:: Mut ;
6+ use crate :: ptr:: { Own , Ref } ;
57use crate :: { Error , StdError } ;
68use core:: any:: TypeId ;
79use core:: fmt:: { self , Debug , Display } ;
810use core:: mem:: ManuallyDrop ;
11+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
12+ use core:: ptr;
913use core:: ptr:: NonNull ;
1014
1115#[ cfg( feature = "std" ) ]
@@ -81,9 +85,11 @@ impl Error {
8185 let vtable = & ErrorVTable {
8286 object_drop : object_drop :: < E > ,
8387 object_ref : object_ref :: < E > ,
88+ #[ cfg( anyhow_no_ptr_addr_of) ]
8489 object_mut : object_mut :: < E > ,
8590 object_boxed : object_boxed :: < E > ,
8691 object_downcast : object_downcast :: < E > ,
92+ #[ cfg( anyhow_no_ptr_addr_of) ]
8793 object_downcast_mut : object_downcast_mut :: < E > ,
8894 object_drop_rest : object_drop_front :: < E > ,
8995 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -103,10 +109,11 @@ impl Error {
103109 let vtable = & ErrorVTable {
104110 object_drop : object_drop :: < MessageError < M > > ,
105111 object_ref : object_ref :: < MessageError < M > > ,
106- #[ cfg( feature = "std" ) ]
112+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
107113 object_mut : object_mut :: < MessageError < M > > ,
108114 object_boxed : object_boxed :: < MessageError < M > > ,
109115 object_downcast : object_downcast :: < M > ,
116+ #[ cfg( anyhow_no_ptr_addr_of) ]
110117 object_downcast_mut : object_downcast_mut :: < M > ,
111118 object_drop_rest : object_drop_front :: < M > ,
112119 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -127,10 +134,11 @@ impl Error {
127134 let vtable = & ErrorVTable {
128135 object_drop : object_drop :: < DisplayError < M > > ,
129136 object_ref : object_ref :: < DisplayError < M > > ,
130- #[ cfg( feature = "std" ) ]
137+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
131138 object_mut : object_mut :: < DisplayError < M > > ,
132139 object_boxed : object_boxed :: < DisplayError < M > > ,
133140 object_downcast : object_downcast :: < M > ,
141+ #[ cfg( anyhow_no_ptr_addr_of) ]
134142 object_downcast_mut : object_downcast_mut :: < M > ,
135143 object_drop_rest : object_drop_front :: < M > ,
136144 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -153,9 +161,11 @@ impl Error {
153161 let vtable = & ErrorVTable {
154162 object_drop : object_drop :: < ContextError < C , E > > ,
155163 object_ref : object_ref :: < ContextError < C , E > > ,
164+ #[ cfg( anyhow_no_ptr_addr_of) ]
156165 object_mut : object_mut :: < ContextError < C , E > > ,
157166 object_boxed : object_boxed :: < ContextError < C , E > > ,
158167 object_downcast : context_downcast :: < C , E > ,
168+ #[ cfg( anyhow_no_ptr_addr_of) ]
159169 object_downcast_mut : context_downcast_mut :: < C , E > ,
160170 object_drop_rest : context_drop_rest :: < C , E > ,
161171 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -176,9 +186,11 @@ impl Error {
176186 let vtable = & ErrorVTable {
177187 object_drop : object_drop :: < BoxedError > ,
178188 object_ref : object_ref :: < BoxedError > ,
189+ #[ cfg( anyhow_no_ptr_addr_of) ]
179190 object_mut : object_mut :: < BoxedError > ,
180191 object_boxed : object_boxed :: < BoxedError > ,
181192 object_downcast : object_downcast :: < Box < dyn StdError + Send + Sync > > ,
193+ #[ cfg( anyhow_no_ptr_addr_of) ]
182194 object_downcast_mut : object_downcast_mut :: < Box < dyn StdError + Send + Sync > > ,
183195 object_drop_rest : object_drop_front :: < Box < dyn StdError + Send + Sync > > ,
184196 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -284,10 +296,11 @@ impl Error {
284296 let vtable = & ErrorVTable {
285297 object_drop : object_drop :: < ContextError < C , Error > > ,
286298 object_ref : object_ref :: < ContextError < C , Error > > ,
287- #[ cfg( feature = "std" ) ]
299+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
288300 object_mut : object_mut :: < ContextError < C , Error > > ,
289301 object_boxed : object_boxed :: < ContextError < C , Error > > ,
290302 object_downcast : context_chain_downcast :: < C > ,
303+ #[ cfg( anyhow_no_ptr_addr_of) ]
291304 object_downcast_mut : context_chain_downcast_mut :: < C > ,
292305 object_drop_rest : context_chain_drop_rest :: < C > ,
293306 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -396,14 +409,20 @@ impl Error {
396409 E : Display + Debug + Send + Sync + ' static ,
397410 {
398411 let target = TypeId :: of :: < E > ( ) ;
412+ let inner = self . inner . by_mut ( ) ;
399413 unsafe {
400414 // Use vtable to find NonNull<()> which points to a value of type E
401415 // somewhere inside the data structure.
402- let addr =
403- match ( vtable ( self . inner . ptr ) . object_downcast_mut ) ( self . inner . by_mut ( ) , target) {
404- Some ( addr) => addr. extend ( ) ,
405- None => return Err ( self ) ,
406- } ;
416+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
417+ let addr = match ( vtable ( inner. ptr ) . object_downcast ) ( inner. by_ref ( ) , target) {
418+ Some ( addr) => addr. by_mut ( ) . extend ( ) ,
419+ None => return Err ( self ) ,
420+ } ;
421+ #[ cfg( anyhow_no_ptr_addr_of) ]
422+ let addr = match ( vtable ( inner. ptr ) . object_downcast_mut ) ( inner, target) {
423+ Some ( addr) => addr. extend ( ) ,
424+ None => return Err ( self ) ,
425+ } ;
407426
408427 // Prepare to read E out of the data structure. We'll drop the rest
409428 // of the data structure separately so that E is not dropped.
@@ -477,7 +496,14 @@ impl Error {
477496 unsafe {
478497 // Use vtable to find NonNull<()> which points to a value of type E
479498 // somewhere inside the data structure.
499+
500+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
501+ let addr =
502+ ( vtable ( self . inner . ptr ) . object_downcast ) ( self . inner . by_ref ( ) , target) ?. by_mut ( ) ;
503+
504+ #[ cfg( anyhow_no_ptr_addr_of) ]
480505 let addr = ( vtable ( self . inner . ptr ) . object_downcast_mut ) ( self . inner . by_mut ( ) , target) ?;
506+
481507 Some ( addr. cast :: < E > ( ) . deref_mut ( ) )
482508 }
483509 }
@@ -537,10 +563,11 @@ impl Drop for Error {
537563struct ErrorVTable {
538564 object_drop : unsafe fn ( Own < ErrorImpl > ) ,
539565 object_ref : unsafe fn ( Ref < ErrorImpl > ) -> Ref < dyn StdError + Send + Sync + ' static > ,
540- #[ cfg( feature = "std" ) ]
566+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
541567 object_mut : unsafe fn ( Mut < ErrorImpl > ) -> & mut ( dyn StdError + Send + Sync + ' static ) ,
542568 object_boxed : unsafe fn ( Own < ErrorImpl > ) -> Box < dyn StdError + Send + Sync + ' static > ,
543569 object_downcast : unsafe fn ( Ref < ErrorImpl > , TypeId ) -> Option < Ref < ( ) > > ,
570+ #[ cfg( anyhow_no_ptr_addr_of) ]
544571 object_downcast_mut : unsafe fn ( Mut < ErrorImpl > , TypeId ) -> Option < Mut < ( ) > > ,
545572 object_drop_rest : unsafe fn ( Own < ErrorImpl > , TypeId ) ,
546573 #[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -571,12 +598,21 @@ where
571598 E : StdError + Send + Sync + ' static ,
572599{
573600 // Attach E's native StdError vtable onto a pointer to self._object.
574- Ref :: new ( & e. cast :: < ErrorImpl < E > > ( ) . deref ( ) . _object )
601+
602+ let unerased = e. cast :: < ErrorImpl < E > > ( ) ;
603+
604+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
605+ return Ref :: from_raw ( NonNull :: new_unchecked (
606+ ptr:: addr_of!( ( * unerased. as_ptr( ) ) . _object) as * mut E ,
607+ ) ) ;
608+
609+ #[ cfg( anyhow_no_ptr_addr_of) ]
610+ return Ref :: new ( & unerased. deref ( ) . _object ) ;
575611}
576612
577613// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
578614// from a `&mut`
579- #[ cfg( feature = "std" ) ]
615+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
580616unsafe fn object_mut < E > ( e : Mut < ErrorImpl > ) -> & mut ( dyn StdError + Send + Sync + ' static )
581617where
582618 E : StdError + Send + Sync + ' static ,
@@ -602,14 +638,26 @@ where
602638 if TypeId :: of :: < E > ( ) == target {
603639 // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
604640 // pointer to its E field.
605- let unerased = e. cast :: < ErrorImpl < E > > ( ) . deref ( ) ;
606- Some ( Ref :: new ( & unerased. _object ) . cast :: < ( ) > ( ) )
641+
642+ let unerased = e. cast :: < ErrorImpl < E > > ( ) ;
643+
644+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
645+ return Some (
646+ Ref :: from_raw ( NonNull :: new_unchecked (
647+ ptr:: addr_of!( ( * unerased. as_ptr( ) ) . _object) as * mut E ,
648+ ) )
649+ . cast :: < ( ) > ( ) ,
650+ ) ;
651+
652+ #[ cfg( anyhow_no_ptr_addr_of) ]
653+ return Some ( Ref :: new ( & unerased. deref ( ) . _object ) . cast :: < ( ) > ( ) ) ;
607654 } else {
608655 None
609656 }
610657}
611658
612659// Safety: requires layout of *e to match ErrorImpl<E>.
660+ #[ cfg( anyhow_no_ptr_addr_of) ]
613661unsafe fn object_downcast_mut < E > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
614662where
615663 E : ' static ,
@@ -649,7 +697,7 @@ where
649697}
650698
651699// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
652- #[ cfg( feature = "std" ) ]
700+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
653701unsafe fn context_downcast_mut < C , E > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
654702where
655703 C : ' static ,
@@ -705,6 +753,7 @@ where
705753}
706754
707755// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
756+ #[ cfg( anyhow_no_ptr_addr_of) ]
708757unsafe fn context_chain_downcast_mut < C > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
709758where
710759 C : ' static ,
@@ -805,7 +854,14 @@ impl ErrorImpl {
805854 pub ( crate ) unsafe fn error_mut ( this : Mut < Self > ) -> & mut ( dyn StdError + Send + Sync + ' static ) {
806855 // Use vtable to attach E's native StdError vtable for the right
807856 // original type E.
808- ( vtable ( this. ptr ) . object_mut ) ( this)
857+
858+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
859+ return ( vtable ( this. ptr ) . object_ref ) ( this. by_ref ( ) )
860+ . by_mut ( )
861+ . deref_mut ( ) ;
862+
863+ #[ cfg( anyhow_no_ptr_addr_of) ]
864+ return ( vtable ( this. ptr ) . object_mut ) ( this) ;
809865 }
810866
811867 #[ cfg( any( backtrace, feature = "backtrace" ) ) ]
0 commit comments