1
1
use crate :: alloc:: Box ;
2
2
use crate :: backtrace:: Backtrace ;
3
3
use 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 } ;
5
7
use crate :: { Error , StdError } ;
6
8
use core:: any:: TypeId ;
7
9
use core:: fmt:: { self , Debug , Display } ;
8
10
use core:: mem:: ManuallyDrop ;
11
+ #[ cfg( not( anyhow_no_ptr_addr_of) ) ]
12
+ use core:: ptr;
9
13
use core:: ptr:: NonNull ;
10
14
11
15
#[ cfg( feature = "std" ) ]
@@ -81,9 +85,11 @@ impl Error {
81
85
let vtable = & ErrorVTable {
82
86
object_drop : object_drop :: < E > ,
83
87
object_ref : object_ref :: < E > ,
88
+ #[ cfg( anyhow_no_ptr_addr_of) ]
84
89
object_mut : object_mut :: < E > ,
85
90
object_boxed : object_boxed :: < E > ,
86
91
object_downcast : object_downcast :: < E > ,
92
+ #[ cfg( anyhow_no_ptr_addr_of) ]
87
93
object_downcast_mut : object_downcast_mut :: < E > ,
88
94
object_drop_rest : object_drop_front :: < E > ,
89
95
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -103,10 +109,11 @@ impl Error {
103
109
let vtable = & ErrorVTable {
104
110
object_drop : object_drop :: < MessageError < M > > ,
105
111
object_ref : object_ref :: < MessageError < M > > ,
106
- #[ cfg( feature = "std" ) ]
112
+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
107
113
object_mut : object_mut :: < MessageError < M > > ,
108
114
object_boxed : object_boxed :: < MessageError < M > > ,
109
115
object_downcast : object_downcast :: < M > ,
116
+ #[ cfg( anyhow_no_ptr_addr_of) ]
110
117
object_downcast_mut : object_downcast_mut :: < M > ,
111
118
object_drop_rest : object_drop_front :: < M > ,
112
119
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -127,10 +134,11 @@ impl Error {
127
134
let vtable = & ErrorVTable {
128
135
object_drop : object_drop :: < DisplayError < M > > ,
129
136
object_ref : object_ref :: < DisplayError < M > > ,
130
- #[ cfg( feature = "std" ) ]
137
+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
131
138
object_mut : object_mut :: < DisplayError < M > > ,
132
139
object_boxed : object_boxed :: < DisplayError < M > > ,
133
140
object_downcast : object_downcast :: < M > ,
141
+ #[ cfg( anyhow_no_ptr_addr_of) ]
134
142
object_downcast_mut : object_downcast_mut :: < M > ,
135
143
object_drop_rest : object_drop_front :: < M > ,
136
144
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -153,9 +161,11 @@ impl Error {
153
161
let vtable = & ErrorVTable {
154
162
object_drop : object_drop :: < ContextError < C , E > > ,
155
163
object_ref : object_ref :: < ContextError < C , E > > ,
164
+ #[ cfg( anyhow_no_ptr_addr_of) ]
156
165
object_mut : object_mut :: < ContextError < C , E > > ,
157
166
object_boxed : object_boxed :: < ContextError < C , E > > ,
158
167
object_downcast : context_downcast :: < C , E > ,
168
+ #[ cfg( anyhow_no_ptr_addr_of) ]
159
169
object_downcast_mut : context_downcast_mut :: < C , E > ,
160
170
object_drop_rest : context_drop_rest :: < C , E > ,
161
171
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -176,9 +186,11 @@ impl Error {
176
186
let vtable = & ErrorVTable {
177
187
object_drop : object_drop :: < BoxedError > ,
178
188
object_ref : object_ref :: < BoxedError > ,
189
+ #[ cfg( anyhow_no_ptr_addr_of) ]
179
190
object_mut : object_mut :: < BoxedError > ,
180
191
object_boxed : object_boxed :: < BoxedError > ,
181
192
object_downcast : object_downcast :: < Box < dyn StdError + Send + Sync > > ,
193
+ #[ cfg( anyhow_no_ptr_addr_of) ]
182
194
object_downcast_mut : object_downcast_mut :: < Box < dyn StdError + Send + Sync > > ,
183
195
object_drop_rest : object_drop_front :: < Box < dyn StdError + Send + Sync > > ,
184
196
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -284,10 +296,11 @@ impl Error {
284
296
let vtable = & ErrorVTable {
285
297
object_drop : object_drop :: < ContextError < C , Error > > ,
286
298
object_ref : object_ref :: < ContextError < C , Error > > ,
287
- #[ cfg( feature = "std" ) ]
299
+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
288
300
object_mut : object_mut :: < ContextError < C , Error > > ,
289
301
object_boxed : object_boxed :: < ContextError < C , Error > > ,
290
302
object_downcast : context_chain_downcast :: < C > ,
303
+ #[ cfg( anyhow_no_ptr_addr_of) ]
291
304
object_downcast_mut : context_chain_downcast_mut :: < C > ,
292
305
object_drop_rest : context_chain_drop_rest :: < C > ,
293
306
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -396,14 +409,20 @@ impl Error {
396
409
E : Display + Debug + Send + Sync + ' static ,
397
410
{
398
411
let target = TypeId :: of :: < E > ( ) ;
412
+ let inner = self . inner . by_mut ( ) ;
399
413
unsafe {
400
414
// Use vtable to find NonNull<()> which points to a value of type E
401
415
// 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
+ } ;
407
426
408
427
// Prepare to read E out of the data structure. We'll drop the rest
409
428
// of the data structure separately so that E is not dropped.
@@ -477,7 +496,14 @@ impl Error {
477
496
unsafe {
478
497
// Use vtable to find NonNull<()> which points to a value of type E
479
498
// 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) ]
480
505
let addr = ( vtable ( self . inner . ptr ) . object_downcast_mut ) ( self . inner . by_mut ( ) , target) ?;
506
+
481
507
Some ( addr. cast :: < E > ( ) . deref_mut ( ) )
482
508
}
483
509
}
@@ -536,11 +562,12 @@ impl Drop for Error {
536
562
537
563
struct ErrorVTable {
538
564
object_drop : unsafe fn ( Own < ErrorImpl > ) ,
539
- object_ref : unsafe fn ( Ref < ErrorImpl > ) -> & ( dyn StdError + Send + Sync + ' static ) ,
540
- #[ cfg( feature = "std" ) ]
565
+ object_ref : unsafe fn ( Ref < ErrorImpl > ) -> Ref < dyn StdError + Send + Sync + ' static > ,
566
+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
541
567
object_mut : unsafe fn ( Mut < ErrorImpl > ) -> & mut ( dyn StdError + Send + Sync + ' static ) ,
542
568
object_boxed : unsafe fn ( Own < ErrorImpl > ) -> Box < dyn StdError + Send + Sync + ' static > ,
543
569
object_downcast : unsafe fn ( Ref < ErrorImpl > , TypeId ) -> Option < Ref < ( ) > > ,
570
+ #[ cfg( anyhow_no_ptr_addr_of) ]
544
571
object_downcast_mut : unsafe fn ( Mut < ErrorImpl > , TypeId ) -> Option < Mut < ( ) > > ,
545
572
object_drop_rest : unsafe fn ( Own < ErrorImpl > , TypeId ) ,
546
573
#[ cfg( all( not( backtrace) , feature = "backtrace" ) ) ]
@@ -566,17 +593,26 @@ unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
566
593
}
567
594
568
595
// Safety: requires layout of *e to match ErrorImpl<E>.
569
- unsafe fn object_ref < E > ( e : Ref < ErrorImpl > ) -> & ( dyn StdError + Send + Sync + ' static )
596
+ unsafe fn object_ref < E > ( e : Ref < ErrorImpl > ) -> Ref < dyn StdError + Send + Sync + ' static >
570
597
where
571
598
E : StdError + Send + Sync + ' static ,
572
599
{
573
600
// Attach E's native StdError vtable onto a pointer to self._object.
574
- & 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 ) ;
575
611
}
576
612
577
613
// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
578
614
// from a `&mut`
579
- #[ cfg( feature = "std" ) ]
615
+ #[ cfg( all ( feature = "std" , anyhow_no_ptr_addr_of ) ) ]
580
616
unsafe fn object_mut < E > ( e : Mut < ErrorImpl > ) -> & mut ( dyn StdError + Send + Sync + ' static )
581
617
where
582
618
E : StdError + Send + Sync + ' static ,
@@ -602,14 +638,26 @@ where
602
638
if TypeId :: of :: < E > ( ) == target {
603
639
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
604
640
// 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 :: < ( ) > ( ) ) ;
607
654
} else {
608
655
None
609
656
}
610
657
}
611
658
612
659
// Safety: requires layout of *e to match ErrorImpl<E>.
660
+ #[ cfg( anyhow_no_ptr_addr_of) ]
613
661
unsafe fn object_downcast_mut < E > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
614
662
where
615
663
E : ' static ,
@@ -649,7 +697,7 @@ where
649
697
}
650
698
651
699
// 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 ) ) ]
653
701
unsafe fn context_downcast_mut < C , E > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
654
702
where
655
703
C : ' static ,
@@ -705,6 +753,7 @@ where
705
753
}
706
754
707
755
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
756
+ #[ cfg( anyhow_no_ptr_addr_of) ]
708
757
unsafe fn context_chain_downcast_mut < C > ( e : Mut < ErrorImpl > , target : TypeId ) -> Option < Mut < ( ) > >
709
758
where
710
759
C : ' static ,
@@ -798,14 +847,21 @@ impl ErrorImpl {
798
847
pub ( crate ) unsafe fn error ( this : Ref < Self > ) -> & ( dyn StdError + Send + Sync + ' static ) {
799
848
// Use vtable to attach E's native StdError vtable for the right
800
849
// original type E.
801
- ( vtable ( this. ptr ) . object_ref ) ( this)
850
+ ( vtable ( this. ptr ) . object_ref ) ( this) . deref ( )
802
851
}
803
852
804
853
#[ cfg( feature = "std" ) ]
805
854
pub ( crate ) unsafe fn error_mut ( this : Mut < Self > ) -> & mut ( dyn StdError + Send + Sync + ' static ) {
806
855
// Use vtable to attach E's native StdError vtable for the right
807
856
// 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) ;
809
865
}
810
866
811
867
#[ cfg( any( backtrace, feature = "backtrace" ) ) ]
0 commit comments