Struct Context

Source
pub struct Context<P> { /* private fields */ }
Expand description

The launch pad for a thread checked for the expected panic type.

The generic type Context serves as the type system’s anchor for the expected type of the panic value, which is given as the type parameter. It can be constructed from an std::thread::Builder providing a customized thread configuration.

The method spawn() is used to spawn a new thread, similarly to how the function std::thread::spawn() works. See the documentation of the spawn() method for detailed description and examples.

§Examples

The example below demonstrates how to construct a Context from a configured std::thread::Builder using the implementation of the standard trait From.

use panic_control::Context;
use std::thread;

#[derive(Debug, PartialEq, Eq)]
struct ExpectedToken;

let thread_builder = thread::Builder::new()
                     .name("My panicky thread".into())
                     .stack_size(65 * 1024);
let ctx = Context::<ExpectedToken>::from(thread_builder);
let h = ctx.spawn(|| {
    // ...
});
h.join().unwrap();

Implementations§

Source§

impl<P: Any> Context<P>

Source

pub fn new() -> Context<P>

Constructs a context with the default thread configuration.

The type parameter can be specified explicitly:

let ctx = Context::<Expected>::new();
Source

pub fn spawn<T, F>(self, f: F) -> CheckedJoinHandle<T, P>
where F: FnOnce() -> T + Send + 'static, T: Send + 'static,

Spawns a new thread taking ownership of the Context, and returns the CheckedJoinHandle for the thread. Other than the return value, and panicking on an OS failure to create a thread, this method behaves exactly like the spawn() method of std::thread::Builder does, and if the Context was constructed from a std::thread::Builder, its thread configuration will be applied.

§Panics

Panics if the underlying call to std::thread::Builder::spawn() returns an Err value. Any panics that function can cause apply as well.

§Examples

The example below uses some kludges to work around a compiler quirk:

let ctx = Context::<Expected>::new();

#[allow(unreachable_code)]
let h = ctx.spawn(|| {
    panic!(Expected(42));
    ()
});

let outcome = h.join().unwrap();
assert_eq!(outcome, Outcome::Panicked(Expected(42)));

Note that unless the unreachable return expression is present, the compiler would have no information to infer the unspecified first type parameter of Outcome, so it would settle on a default type that is going to be changed to ! in Rust 1.26. In previous versions of the compiler, code that invokes this behavior is denied by a lint, so the following example does not compile:

let ctx = Context::<Expected>::new();
let h = ctx.spawn(|| {
    panic!(Expected(42));
});
let outcome = h.join().unwrap();
assert_eq!(outcome, Outcome::Panicked(Expected(42)));

A way to avoid the future incompatibility without resorting to warning overrides is to match the Outcome value without touching the sensitive parts:

let ctx = Context::<Expected>::new();
let h = ctx.spawn(|| {
    panic!(Expected(42));
});
let outcome = h.join().unwrap();
match outcome {
    Outcome::Panicked(Expected(n)) => assert_eq!(n, 42),
    _ => panic!("join() returned an unexpected Outcome value")
}
Source

pub fn spawn_quiet<T, F>(self, f: F) -> CheckedJoinHandle<T, P>
where F: FnOnce() -> T + Send + 'static, T: Send + 'static,

Like spawn(), but disables the panic hook if the spawned thread panics.

The process-global panic hook, either installed with std::panic::set_hook() or the standard library default, gets augmented with a filter that disables invocation of the hook closure if the spawned thread panics.

This function can be used in any order together with other functions and methods of this crate that modify the panic hook.

§Caveats

Note that the suppression can apply to the default panic hook that is normally used to report assertion failures and other unexpected panics on the standard error stream. The only remaining way to observe the panic is by checking the result of join() for the spawned thread.

Other code within the program that modifies the panic hook, concurrently to, or after, a call to this function, may cause the suppression not to work as intended. See the documentation on the function disable_hook_in_current_thread() for possible pitfalls.

§Examples
let ctx = Context::<Expected>::new();
let h = ctx.spawn_quiet(|| {
    assert!(false, "I'm panicking, \
        but you can only learn about it through join()");
});
let res = h.join();
assert!(res.is_err());

Trait Implementations§

Source§

impl<P> Debug for Context<P>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<P: Any> Default for Context<P>

Source§

fn default() -> Context<P>

Returns the “default value” for a type. Read more
Source§

impl<P: Any> From<Builder> for Context<P>

Source§

fn from(builder: Builder) -> Context<P>

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<P> Freeze for Context<P>

§

impl<P> RefUnwindSafe for Context<P>
where P: RefUnwindSafe,

§

impl<P> Send for Context<P>
where P: Send,

§

impl<P> Sync for Context<P>
where P: Sync,

§

impl<P> Unpin for Context<P>
where P: Unpin,

§

impl<P> UnwindSafe for Context<P>
where P: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.