You're talking about resume_unwind, which is the other half of catch_unwind. Run the test case inside catch_unwind, save the result, do the cleanup, then use resume_unwind to continue. Something like:
#[test]
fn crashy_test() {
let res = std::panic::catch_unwind(|| do_crashy_test());
clean_up_after_test();
match res {
Ok(ok) => it_didnt_panic(ok),
Err(panic) => std::panic::resume_unwind(panic),
}
}
Note, though, that this is manual and error prone. A better option is to use Drop to clean up at the end of a scope - unwinding runs Drop::drop for you:
struct Cleanup;
impl Drop for Cleanup {
fn drop(&mut self) {
clean_up_after_test();
}
}
#[test]
fn crashy_test() {
let _cleanup = Cleanup;
let res = do_crashy_test();
it_didnt_panic(res);
}