File tree Expand file tree Collapse file tree 2 files changed +31
-1
lines changed Expand file tree Collapse file tree 2 files changed +31
-1
lines changed Original file line number Diff line number Diff line change @@ -232,7 +232,12 @@ pub unsafe trait ErasablePtr {
232232 Self : Sized ,
233233 F : FnOnce ( & mut Self ) -> T ,
234234 {
235- f ( & mut ManuallyDrop :: new ( & mut Self :: unerase ( * this) ) )
235+ // SAFETY: guard is required to write potentially changed pointer value, even on unwind
236+ let mut that = scopeguard:: guard ( ManuallyDrop :: new ( Self :: unerase ( * this) ) , |unerased| {
237+ ptr:: write ( this, ErasablePtr :: erase ( ManuallyDrop :: into_inner ( unerased) ) ) ;
238+ } ) ;
239+
240+ f ( & mut that)
236241 }
237242}
238243
Original file line number Diff line number Diff line change @@ -61,4 +61,29 @@ fn with_mut_fn() {
6161 assert_ne ! ( * bigbox, Default :: default ( ) ) ;
6262 } )
6363 }
64+
65+ // drop it, otherwise we would leak memory here
66+ unsafe { <Box < Big > as ErasablePtr >:: unerase ( erased) } ;
67+ }
68+
69+ #[ test]
70+ fn with_mut_fn_replacethis ( ) {
71+ let boxed: Box < Big > = Default :: default ( ) ;
72+
73+ let mut erased: ErasedPtr = ErasablePtr :: erase ( boxed) ;
74+ let e1 = erased. as_ptr ( ) as usize ;
75+ unsafe {
76+ <Box < Big > as ErasablePtr >:: with_mut ( & mut erased, |bigbox| {
77+ let mut newboxed: Box < Big > = Default :: default ( ) ;
78+ newboxed. 0 [ 0 ] = 123456 ;
79+ * bigbox = newboxed;
80+ assert_ne ! ( * bigbox, Default :: default ( ) ) ;
81+ } )
82+ }
83+
84+ let e2 = erased. as_ptr ( ) as usize ;
85+ assert_ne ! ( e1, e2) ;
86+
87+ // drop it, otherwise we would leak memory here
88+ unsafe { <Box < Big > as ErasablePtr >:: unerase ( erased) } ;
6489}
You can’t perform that action at this time.
0 commit comments