]> git.lizzy.rs Git - rust.git/blob - tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/main.rs
Rollup merge of #106670 - albertlarsan68:check-docs-in-pr-ci, r=Mark-Simulacrum
[rust.git] / tests / run-make-fulldeps / c-unwind-abi-catch-lib-panic / main.rs
1 //! A test for calling `C-unwind` functions across foreign function boundaries.
2 //!
3 //! This test triggers a panic in a Rust library that our foreign function invokes. This shows
4 //! that we can unwind through the C code in that library, and catch the underlying panic.
5 #![feature(c_unwind)]
6
7 use std::panic::{catch_unwind, AssertUnwindSafe};
8
9 fn main() {
10     // Call `add_small_numbers`, passing arguments that will NOT trigger a panic.
11     let (a, b) = (9, 1);
12     let c = unsafe { add_small_numbers(a, b) };
13     assert_eq!(c, 10);
14
15     // Call `add_small_numbers`, passing arguments that will trigger a panic, and catch it.
16     let caught_unwind = catch_unwind(AssertUnwindSafe(|| {
17         let (a, b) = (10, 1);
18         let _c = unsafe { add_small_numbers(a, b) };
19         unreachable!("should have unwound instead of returned");
20     }));
21
22     // Assert that we did indeed panic, then unwrap and downcast the panic into the sum.
23     assert!(caught_unwind.is_err());
24     let panic_obj = caught_unwind.unwrap_err();
25     let msg = panic_obj.downcast_ref::<String>().unwrap();
26     assert_eq!(msg, "11");
27 }
28
29 #[link(name = "add", kind = "static")]
30 extern "C-unwind" {
31     /// An external function, defined in C.
32     ///
33     /// Returns the sum of two numbers, or panics if the sum is greater than 10.
34     fn add_small_numbers(a: u32, b: u32) -> u32;
35 }