diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fa07b0f761b4e..e97b015283bcb 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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)] diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 69a1b57a0c538..5c2e36623cbed 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -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 DerefMut for AssertRecoverSafe { } } +impl R> FnOnce<()> for AssertRecoverSafe { + 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