Skip to content

Commit

Permalink
std: Rename thread::catch_panic to panic::recover
Browse files Browse the repository at this point in the history
This commit is an implementation of [RFC 1236][rfc] which renames the
`thread::catch_panic` function to `panic::recover` while also removing the
`Send` bound (but leaving the `'static` bound).

[rfc]: rust-lang/rfcs#1236

cc rust-lang#27719
  • Loading branch information
alexcrichton committed Aug 31, 2015
1 parent 8dba06a commit a871a4b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod panic;
pub mod path;
pub mod process;
pub mod sync;
Expand Down
63 changes: 63 additions & 0 deletions src/libstd/panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Panic support in the standard library
#![unstable(feature = "std_panic", reason = "module recently added",
issue = "27719")]

use thread::Result;

/// Invokes a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok` with the closure's result if the closure
/// does not panic, and will return `Err(cause)` if the closure panics. The
/// `cause` returned is the object with which panic was originally invoked.
///
/// It is currently undefined behavior to unwind from Rust code into foreign
/// code, so this function is particularly useful when Rust is called from
/// another language (normally C). This can run arbitrary Rust code, capturing a
/// panic and allowing a graceful handling of the error.
///
/// It is **not** recommended to use this function for a general try/catch
/// mechanism. The `Result` type is more appropriate to use for functions that
/// can fail on a regular basis.
///
/// The closure provided is required to adhere to the `'static` bound to ensure
/// that it cannot reference data in the parent stack frame, mitigating problems
/// with exception safety.
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
/// println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = panic::recover(|| {
/// panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
#[unstable(feature = "recover", reason = "recent API addition",
issue = "27719")]
pub fn recover<F, R>(f: F) -> Result<R> where F: FnOnce() -> R + 'static {
let mut result = None;
unsafe {
let result = &mut result;
try!(::rt::unwind::try(move || *result = Some(f())))
}
Ok(result.unwrap())
}
4 changes: 2 additions & 2 deletions src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
issue = "0")]
#![allow(missing_docs)]

use panic;
use prelude::v1::*;
use sys;
use thread;

// Reexport some of our utilities which are expected by other crates.
pub use self::util::min_stack;
Expand Down Expand Up @@ -96,7 +96,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
args::init(argc, argv);

// And finally, let's run some code!
let res = thread::catch_panic(mem::transmute::<_, fn()>(main));
let res = panic::recover(mem::transmute::<_, fn()>(main));
cleanup();
res.is_err()
};
Expand Down
19 changes: 1 addition & 18 deletions src/libstd/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,26 +357,9 @@ pub fn panicking() -> bool {
/// with exception safety. Furthermore, a `Send` bound is also required,
/// providing the same safety guarantees as `thread::spawn` (ensuring the
/// closure is properly isolated from the parent).
///
/// # Examples
///
/// ```
/// #![feature(catch_panic)]
///
/// use std::thread;
///
/// let result = thread::catch_panic(|| {
/// println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = thread::catch_panic(|| {
/// panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
#[unstable(feature = "catch_panic", reason = "recent API addition",
issue = "27719")]
#[deprecated(since = "1.4.0", reason = "renamed to std::panic::recover")]
pub fn catch_panic<F, R>(f: F) -> Result<R>
where F: FnOnce() -> R + Send + 'static
{
Expand Down
6 changes: 3 additions & 3 deletions src/test/run-pass/binary-heap-panic-safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(std_misc, collections, catch_panic, rand, sync_poison)]
#![feature(collections, recover, std_panic, rand)]

use std::__rand::{thread_rng, Rng};
use std::thread;
use std::panic;

use std::collections::BinaryHeap;
use std::cmp;
Expand Down Expand Up @@ -74,7 +74,7 @@ fn test_integrity() {


// push the panicking item to the heap and catch the panic
let thread_result = thread::catch_panic(move || {
let thread_result = panic::recover(move || {
heap.lock().unwrap().push(panic_item);
});
assert!(thread_result.is_err());
Expand Down
8 changes: 4 additions & 4 deletions src/test/run-pass/running-with-no-runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(catch_panic, start)]
#![feature(std_panic, recover, start)]

use std::ffi::CStr;
use std::process::{Command, Output};
use std::thread;
use std::panic;
use std::str;

#[start]
Expand All @@ -22,8 +22,8 @@ fn start(argc: isize, argv: *const *const u8) -> isize {
match **argv.offset(1) as char {
'1' => {}
'2' => println!("foo"),
'3' => assert!(thread::catch_panic(|| {}).is_ok()),
'4' => assert!(thread::catch_panic(|| panic!()).is_err()),
'3' => assert!(panic::recover(|| {}).is_ok()),
'4' => assert!(panic::recover(|| panic!()).is_err()),
'5' => assert!(Command::new("test").spawn().is_err()),
_ => panic!()
}
Expand Down

0 comments on commit a871a4b

Please sign in to comment.