File tree Expand file tree Collapse file tree 1 file changed +10
-2
lines changed Expand file tree Collapse file tree 1 file changed +10
-2
lines changed Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ use syntax_pos::Span;
2121
2222use rustc_data_structures:: sync:: Lrc ;
2323use std:: ops:: DerefMut ;
24+ use std:: { panic, process, ptr} ;
2425
2526pub trait ExpectOne < A : Array > {
2627 fn expect_one ( self , err : & ' static str ) -> A :: Item ;
@@ -305,11 +306,18 @@ pub trait MutVisitor: Sized {
305306
306307/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
307308/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
308- /// method.
309+ /// method. Abort the program if the closure panics.
309310//
310311// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
311312pub fn visit_clobber < T , F > ( t : & mut T , f : F ) where F : FnOnce ( T ) -> T {
312- unsafe { std:: ptr:: write ( t, f ( std:: ptr:: read ( t) ) ) ; }
313+ unsafe {
314+ // Safe because `t` is used in a read-only fashion by `read()` before
315+ // being overwritten by `write()`.
316+ let old_t = ptr:: read ( t) ;
317+ let new_t = panic:: catch_unwind ( panic:: AssertUnwindSafe ( || f ( old_t) ) )
318+ . unwrap_or_else ( |_| process:: abort ( ) ) ;
319+ ptr:: write ( t, new_t) ;
320+ }
313321}
314322
315323// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
You can’t perform that action at this time.
0 commit comments