This repository was archived by the owner on Aug 16, 2021. It is now read-only.
File tree Expand file tree Collapse file tree 4 files changed +19
-77
lines changed Expand file tree Collapse file tree 4 files changed +19
-77
lines changed Original file line number Diff line number Diff line change @@ -7,7 +7,6 @@ license = "MIT OR Apache-2.0"
77name = " failure"
88repository = " https://github.com/rust-lang-nursery/failure"
99version = " 0.1.2"
10- build = " build.rs"
1110
1211[dependencies .failure_derive ]
1312optional = true
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1- use core:: ptr ;
1+ use core:: any :: TypeId ;
22
33use Fail ;
44use backtrace:: Backtrace ;
@@ -38,36 +38,13 @@ impl ErrorImpl {
3838 }
3939
4040 pub ( crate ) fn downcast < T : Fail > ( self ) -> Result < T , ErrorImpl > {
41- let ret: Option < T > = self . failure ( ) . downcast_ref ( ) . map ( |fail| {
42- unsafe {
43- // drop the backtrace
44- let _ = ptr:: read ( & self . inner . backtrace as * const Backtrace ) ;
45- // read out the fail type
46- ptr:: read ( fail as * const T )
47- }
48- } ) ;
49- match ret {
50- Some ( ret) => {
51- // deallocate the box without dropping the inner parts
52- #[ cfg( has_global_alloc) ] {
53- use std:: alloc:: { dealloc, Layout } ;
54- unsafe {
55- let layout = Layout :: for_value ( & * self . inner ) ;
56- let ptr = Box :: into_raw ( self . inner ) ;
57- dealloc ( ptr as * mut u8 , layout) ;
58- }
59- }
60-
61- // slightly leaky versions of the above thing which makes the box
62- // itself leak. There is no good way around this as far as I know.
63- #[ cfg( not( has_global_alloc) ) ] {
64- use core:: mem;
65- mem:: forget ( self ) ;
66- }
67-
68- Ok ( ret)
69- }
70- _ => Err ( self )
41+ if self . failure ( ) . __private_get_type_id__ ( ) == TypeId :: of :: < T > ( ) {
42+ let ErrorImpl { inner } = self ;
43+ let casted = unsafe { Box :: from_raw ( Box :: into_raw ( inner) as * mut Inner < T > ) } ;
44+ let Inner { backtrace : _, failure } = * casted;
45+ Ok ( failure)
46+ } else {
47+ Err ( self )
7148 }
7249 }
7350}
Original file line number Diff line number Diff line change @@ -122,9 +122,6 @@ impl Error {
122122 /// failure is of the type `T`. For this reason it returns a `Result` - in
123123 /// the case that the underlying error is of a different type, the
124124 /// original `Error` is returned.
125- ///
126- /// Note that this method leaks on Rust versions < 1.28.0.
127- #[ cfg_attr( not( has_global_alloc) , deprecated( note = "this method leaks on Rust versions < 1.28" ) ) ]
128125 pub fn downcast < T : Fail > ( self ) -> Result < T , Error > {
129126 self . imp . downcast ( ) . map_err ( |imp| Error { imp } )
130127 }
@@ -230,9 +227,17 @@ mod test {
230227 }
231228
232229 #[ test]
233- fn test_downcast ( ) {
234- let error: Error = io:: Error :: new ( io:: ErrorKind :: NotFound , "test" ) . into ( ) ;
235- let real_io_error = error. downcast_ref :: < io:: Error > ( ) . unwrap ( ) ;
230+ fn downcast_can_be_used ( ) {
231+ let mut error: Error = io:: Error :: new ( io:: ErrorKind :: NotFound , "test" ) . into ( ) ;
232+ {
233+ let real_io_error_ref = error. downcast_ref :: < io:: Error > ( ) . unwrap ( ) ;
234+ assert_eq ! ( real_io_error_ref. to_string( ) , "test" ) ;
235+ }
236+ {
237+ let real_io_error_mut = error. downcast_mut :: < io:: Error > ( ) . unwrap ( ) ;
238+ assert_eq ! ( real_io_error_mut. to_string( ) , "test" ) ;
239+ }
240+ let real_io_error = error. downcast :: < io:: Error > ( ) . unwrap ( ) ;
236241 assert_eq ! ( real_io_error. to_string( ) , "test" ) ;
237242 }
238243}
You can’t perform that action at this time.
0 commit comments