about summary refs log tree commit diff
path: root/src/libstd/panic.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-10 17:52:12 -0800
committerbors <bors@rust-lang.org>2016-03-10 17:52:12 -0800
commitc6a6053112122451bcb39f8d24d6cc86f5a28536 (patch)
tree863ea14eb6ba63b20d00349cd52adbff98ab5b76 /src/libstd/panic.rs
parentc9629d61c6947030666379a6f46445f07849bbd9 (diff)
parentec58f40463e3c12208376c89459975974633382c (diff)
downloadrust-c6a6053112122451bcb39f8d24d6cc86f5a28536.tar.gz
rust-c6a6053112122451bcb39f8d24d6cc86f5a28536.zip
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
Diffstat (limited to 'src/libstd/panic.rs')
-rw-r--r--src/libstd/panic.rs36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 69a1b57a0c5..5c2e36623cb 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<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