about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2016-03-07 09:20:25 -0800
committerAlex Crichton <alex@alexcrichton.com>2016-03-07 11:02:43 -0800
commitec58f40463e3c12208376c89459975974633382c (patch)
tree88f82c1cc80ac25352ea61d904092d3d3614614c /src/libstd
parent72d588a62044b9fae0e5baaba21aa9166b6db9c5 (diff)
downloadrust-ec58f40463e3c12208376c89459975974633382c.tar.gz
rust-ec58f40463e3c12208376c89459975974633382c.zip
std: Add impl of FnOnce to AssertRecoverSafe
This was originally intended, but forgot to land by accident!

cc #27719
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/panic.rs36
2 files changed, 36 insertions, 1 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index fa07b0f761b..e97b015283b 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 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