1 use std::panic;
2 use std::sync::{Arc, Mutex};
3 
test_panic<Func: FnOnce() + panic::UnwindSafe>(func: Func) -> Option<String>4 pub fn test_panic<Func: FnOnce() + panic::UnwindSafe>(func: Func) -> Option<String> {
5     static PANIC_MUTEX: Mutex<()> = Mutex::new(());
6 
7     {
8         let _guard = PANIC_MUTEX.lock();
9         let panic_file: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
10 
11         let prev_hook = panic::take_hook();
12         {
13             let panic_file = panic_file.clone();
14             panic::set_hook(Box::new(move |panic_info| {
15                 let panic_location = panic_info.location().unwrap();
16                 panic_file
17                     .lock()
18                     .unwrap()
19                     .clone_from(&Some(panic_location.file().to_string()));
20             }));
21         }
22 
23         let result = panic::catch_unwind(func);
24         // Return to the previously set panic hook (maybe default) so that we get nice error
25         // messages in the tests.
26         panic::set_hook(prev_hook);
27 
28         if result.is_err() {
29             panic_file.lock().unwrap().clone()
30         } else {
31             None
32         }
33     }
34 }
35