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"
7
7
name = " failure"
8
8
repository = " https://github.com/rust-lang-nursery/failure"
9
9
version = " 0.1.2"
10
- build = " build.rs"
11
10
12
11
[dependencies .failure_derive ]
13
12
optional = 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 ;
2
2
3
3
use Fail ;
4
4
use backtrace:: Backtrace ;
@@ -38,36 +38,13 @@ impl ErrorImpl {
38
38
}
39
39
40
40
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 )
71
48
}
72
49
}
73
50
}
Original file line number Diff line number Diff line change @@ -122,9 +122,6 @@ impl Error {
122
122
/// failure is of the type `T`. For this reason it returns a `Result` - in
123
123
/// the case that the underlying error is of a different type, the
124
124
/// 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" ) ) ]
128
125
pub fn downcast < T : Fail > ( self ) -> Result < T , Error > {
129
126
self . imp . downcast ( ) . map_err ( |imp| Error { imp } )
130
127
}
@@ -230,9 +227,17 @@ mod test {
230
227
}
231
228
232
229
#[ 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 ( ) ;
236
241
assert_eq ! ( real_io_error. to_string( ) , "test" ) ;
237
242
}
238
243
}
You can’t perform that action at this time.
0 commit comments