@@ -22,7 +22,16 @@ use std::backtrace::{Backtrace, BacktraceStatus};
2222/// not lie about whether they are or are not an instance of the given type id's
2323/// associated type (or a newtype wrapper around that type). Violations will
2424/// lead to unsafety.
25- pub ( crate ) unsafe trait ErrorExt : core:: error:: Error + Send + Sync + ' static {
25+ pub ( crate ) unsafe trait ErrorExt : Send + Sync + ' static {
26+ /// Get this error as a shared reference to a `dyn core::error::Error` trait
27+ /// object.
28+ fn ext_as_dyn_core_error ( & self ) -> & ( dyn core:: error:: Error + Send + Sync + ' static ) ;
29+
30+ /// Get this error as a boxed `dyn core::error::Error` trait object.
31+ fn ext_into_boxed_dyn_core_error (
32+ self ,
33+ ) -> Result < Box < dyn core:: error:: Error + Send + Sync + ' static > , OutOfMemory > ;
34+
2635 /// Get a shared borrow of the next error in the chain.
2736 fn ext_source ( & self ) -> Option < OomOrDynErrorRef < ' _ > > ;
2837
@@ -488,6 +497,20 @@ impl From<Error> for Box<dyn core::error::Error + Send + Sync + 'static> {
488497 }
489498}
490499
500+ impl From < Error > for Box < dyn core:: error:: Error + Send + ' static > {
501+ #[ inline]
502+ fn from ( error : Error ) -> Self {
503+ error. into_boxed_dyn_error ( )
504+ }
505+ }
506+
507+ impl From < Error > for Box < dyn core:: error:: Error + ' static > {
508+ #[ inline]
509+ fn from ( error : Error ) -> Self {
510+ error. into_boxed_dyn_error ( )
511+ }
512+ }
513+
491514/// Convert a [`Error`] into an [`anyhow::Error`].
492515///
493516/// # Example
@@ -517,6 +540,28 @@ impl From<Error> for anyhow::Error {
517540 }
518541}
519542
543+ impl core:: ops:: Deref for Error {
544+ type Target = dyn core:: error:: Error + Send + Sync + ' static ;
545+
546+ fn deref ( & self ) -> & Self :: Target {
547+ self . as_ref ( )
548+ }
549+ }
550+
551+ impl AsRef < dyn core:: error:: Error > for Error {
552+ #[ inline]
553+ fn as_ref ( & self ) -> & ( dyn core:: error:: Error + ' static ) {
554+ self . inner . unpack ( ) . as_dyn_core_error ( )
555+ }
556+ }
557+
558+ impl AsRef < dyn core:: error:: Error + Send + Sync > for Error {
559+ #[ inline]
560+ fn as_ref ( & self ) -> & ( dyn core:: error:: Error + Send + Sync + ' static ) {
561+ self . inner . unpack ( ) . as_dyn_core_error ( )
562+ }
563+ }
564+
520565impl Error {
521566 /// Construct a new `Error` from a type that implements
522567 /// `core::error::Error`.
@@ -1107,38 +1152,22 @@ impl Error {
11071152#[ repr( transparent) ]
11081153struct ForeignError < E > ( E ) ;
11091154
1110- impl < E > fmt:: Debug for ForeignError < E >
1111- where
1112- E : core:: error:: Error + Send + Sync + ' static ,
1113- {
1114- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1115- fmt:: Debug :: fmt ( & self . 0 , f)
1116- }
1117- }
1118-
1119- impl < E > fmt:: Display for ForeignError < E >
1155+ // Safety: `ext_is` is correct, `ext_move` always writes to `dest`.
1156+ unsafe impl < E > ErrorExt for ForeignError < E >
11201157where
11211158 E : core:: error:: Error + Send + Sync + ' static ,
11221159{
1123- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
1124- fmt :: Display :: fmt ( & self . 0 , f )
1160+ fn ext_as_dyn_core_error ( & self ) -> & ( dyn core :: error :: Error + Send + Sync + ' static ) {
1161+ & self . 0
11251162 }
1126- }
11271163
1128- impl < E > core:: error:: Error for ForeignError < E >
1129- where
1130- E : core:: error:: Error + Send + Sync + ' static ,
1131- {
1132- fn source ( & self ) -> Option < & ( dyn core:: error:: Error + ' static ) > {
1133- self . 0 . source ( )
1164+ fn ext_into_boxed_dyn_core_error (
1165+ self ,
1166+ ) -> Result < Box < dyn core:: error:: Error + Send + Sync + ' static > , OutOfMemory > {
1167+ let boxed = try_new_uninit_box ( ) ?;
1168+ Ok ( Box :: write ( boxed, self . 0 ) as _ )
11341169 }
1135- }
11361170
1137- // Safety: `ext_is` is correct, `ext_move` always writes to `dest`.
1138- unsafe impl < E > ErrorExt for ForeignError < E >
1139- where
1140- E : core:: error:: Error + Send + Sync + ' static ,
1141- {
11421171 fn ext_source ( & self ) -> Option < OomOrDynErrorRef < ' _ > > {
11431172 None
11441173 }
@@ -1206,6 +1235,17 @@ unsafe impl<M> ErrorExt for MessageError<M>
12061235where
12071236 M : fmt:: Debug + fmt:: Display + Send + Sync + ' static ,
12081237{
1238+ fn ext_as_dyn_core_error ( & self ) -> & ( dyn core:: error:: Error + Send + Sync + ' static ) {
1239+ self
1240+ }
1241+
1242+ fn ext_into_boxed_dyn_core_error (
1243+ self ,
1244+ ) -> Result < Box < dyn core:: error:: Error + Send + Sync + ' static > , OutOfMemory > {
1245+ let boxed = try_new_uninit_box ( ) ?;
1246+ Ok ( Box :: write ( boxed, self ) as _ )
1247+ }
1248+
12091249 fn ext_source ( & self ) -> Option < OomOrDynErrorRef < ' _ > > {
12101250 None
12111251 }
@@ -1247,27 +1287,19 @@ where
12471287#[ repr( transparent) ]
12481288struct BoxedError ( Box < dyn core:: error:: Error + Send + Sync + ' static > ) ;
12491289
1250- impl fmt:: Debug for BoxedError {
1251- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1252- fmt:: Debug :: fmt ( & self . 0 , f)
1290+ // Safety: `ext_is` is implemented correctly and `ext_move` always
1291+ // writes to its pointer.
1292+ unsafe impl ErrorExt for BoxedError {
1293+ fn ext_as_dyn_core_error ( & self ) -> & ( dyn core:: error:: Error + Send + Sync + ' static ) {
1294+ & * self . 0
12531295 }
1254- }
12551296
1256- impl fmt:: Display for BoxedError {
1257- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1258- fmt:: Display :: fmt ( & self . 0 , f)
1297+ fn ext_into_boxed_dyn_core_error (
1298+ self ,
1299+ ) -> Result < Box < dyn core:: error:: Error + Send + Sync + ' static > , OutOfMemory > {
1300+ Ok ( self . 0 )
12591301 }
1260- }
12611302
1262- impl core:: error:: Error for BoxedError {
1263- fn source ( & self ) -> Option < & ( dyn core:: error:: Error + ' static ) > {
1264- self . 0 . source ( )
1265- }
1266- }
1267-
1268- // Safety: `ext_is` is implemented correctly and `ext_move` always
1269- // writes to its pointer.
1270- unsafe impl ErrorExt for BoxedError {
12711303 fn ext_source ( & self ) -> Option < OomOrDynErrorRef < ' _ > > {
12721304 None
12731305 }
@@ -1311,31 +1343,20 @@ unsafe impl ErrorExt for BoxedError {
13111343#[ cfg( feature = "anyhow" ) ]
13121344struct AnyhowError ( anyhow:: Error ) ;
13131345
1346+ // Safety: `ext_is` is implemented correctly and `ext_move` always
1347+ // writes to its pointer.
13141348#[ cfg( feature = "anyhow" ) ]
1315- impl fmt:: Debug for AnyhowError {
1316- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1317- fmt:: Debug :: fmt ( & self . 0 , f)
1318- }
1319- }
1320-
1321- #[ cfg( feature = "anyhow" ) ]
1322- impl fmt:: Display for AnyhowError {
1323- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1324- fmt:: Display :: fmt ( & self . 0 , f)
1349+ unsafe impl ErrorExt for AnyhowError {
1350+ fn ext_as_dyn_core_error ( & self ) -> & ( dyn core:: error:: Error + Send + Sync + ' static ) {
1351+ self . 0 . as_ref ( )
13251352 }
1326- }
13271353
1328- # [ cfg ( feature = "anyhow" ) ]
1329- impl core :: error :: Error for AnyhowError {
1330- fn source ( & self ) -> Option < & ( dyn core:: error:: Error + ' static ) > {
1331- self . 0 . source ( )
1354+ fn ext_into_boxed_dyn_core_error (
1355+ self ,
1356+ ) -> Result < Box < dyn core:: error:: Error + Send + Sync + ' static > , OutOfMemory > {
1357+ Ok ( self . 0 . into_boxed_dyn_error ( ) )
13321358 }
1333- }
13341359
1335- // Safety: `ext_is` is implemented correctly and `ext_move` always
1336- // writes to its pointer.
1337- #[ cfg( feature = "anyhow" ) ]
1338- unsafe impl ErrorExt for AnyhowError {
13391360 fn ext_source ( & self ) -> Option < OomOrDynErrorRef < ' _ > > {
13401361 None
13411362 }
0 commit comments