]> git.lizzy.rs Git - rust.git/blob - src/test/run-make-fulldeps/c-unwind-abi-catch-panic/main.rs
rustdoc-json: Make the `fns/generics.rs` test much more robust
[rust.git] / src / test / run-make-fulldeps / c-unwind-abi-catch-panic / main.rs
1 //! A test for calling `C-unwind` functions across foreign function boundaries.
2 //!
3 //! This test triggers a panic when calling a foreign function that calls *back* into Rust.
4 #![feature(c_unwind)]
5
6 use std::panic::{catch_unwind, AssertUnwindSafe};
7
8 fn main() {
9     // Call `add_small_numbers`, passing arguments that will NOT trigger a panic.
10     let (a, b) = (9, 1);
11     let c = unsafe { add_small_numbers(a, b) };
12     assert_eq!(c, 10);
13
14     // Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
15     let caught_unwind = catch_unwind(AssertUnwindSafe(|| {
16         let (a, b) = (10, 1);
17         let _c = unsafe { add_small_numbers(a, b) };
18         unreachable!("should have unwound instead of returned");
19     }));
20
21     // Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
22     assert!(caught_unwind.is_err());
23     let panic_obj = caught_unwind.unwrap_err();
24     let msg = panic_obj.downcast_ref::<String>().unwrap();
25     assert_eq!(msg, "11");
26 }
27
28 #[link(name = "add", kind = "static")]
29 extern "C-unwind" {
30     /// An external function, defined in C.
31     ///
32     /// Returns the sum of two numbers, or panics if the sum is greater than 10.
33     fn add_small_numbers(a: u32, b: u32) -> u32;
34 }
35
36 /// This function will panic if `x` is greater than 10.
37 ///
38 /// This function is called by `add_small_numbers`.
39 #[no_mangle]
40 pub extern "C-unwind" fn panic_if_greater_than_10(x: u32) {
41     if x > 10 {
42         panic!("{}", x); // That is too big!
43     }
44 }