Auto merge of #32102 - alexcrichton:assert-safe-closures, r=aturon

std: Add impl of FnOnce to AssertRecoverSafe

This was originally intended, but forgot to land by accident!

cc #27719
This commit is contained in:
bors 2016-03-10 17:52:12 -08:00
commit c6a6053112
2 changed files with 36 additions and 1 deletions

View File

@ -230,6 +230,7 @@
#![feature(float_extras)]
#![feature(float_from_str_radix)]
#![feature(fnbox)]
#![feature(fn_traits)]
#![feature(heap_api)]
#![feature(hashmap_hasher)]
#![feature(inclusive_range)]

View File

@ -129,6 +129,9 @@ pub trait RefRecoverSafe {}
///
/// # Examples
///
/// One way to use `AssertRecoverSafe` is to assert that the entire closure
/// itself is recover safe, bypassing all checks for all variables:
///
/// ```
/// #![feature(recover, std_panic)]
///
@ -144,10 +147,33 @@ pub trait RefRecoverSafe {}
/// // });
///
/// // This, however, will compile due to the `AssertRecoverSafe` wrapper
/// let result = panic::recover(AssertRecoverSafe::new(|| {
/// variable += 3;
/// }));
/// // ...
/// ```
///
/// Wrapping the entire closure amounts to a blanket assertion that all captured
/// variables are recover safe. This has the downside that if new captures are
/// added in the future, they will also be considered recover safe. Therefore,
/// you may prefer to just wrap individual captures, as shown below. This is
/// more annotation, but it ensures that if a new capture is added which is not
/// recover safe, you will get a compilation error at that time, which will
/// allow you to consider whether that new capture in fact represent a bug or
/// not.
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic::{self, AssertRecoverSafe};
///
/// let mut variable = 4;
/// let other_capture = 3;
///
/// let result = {
/// let mut wrapper = AssertRecoverSafe::new(&mut variable);
/// panic::recover(move || {
/// **wrapper += 3;
/// **wrapper += other_capture;
/// })
/// };
/// // ...
@ -215,6 +241,14 @@ impl<T> DerefMut for AssertRecoverSafe<T> {
}
}
impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
type Output = R;
extern "rust-call" fn call_once(self, _args: ()) -> R {
(self.0)()
}
}
/// Invokes a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok` with the closure's result if the closure