From 0a218a84a813375cfb38e0ee5c5f8445afb2765c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 18 Dec 2020 12:16:28 -0800 Subject: [PATCH 1/2] Add test of anyhow::Error in ffi signature Currently: warning: `extern` fn uses type `anyhow::Error`, which is not FFI-safe --> tests/test_ffi.rs:6:32 | 6 | pub extern "C" fn anyhow1(err: anyhow::Error) { | ^^^^^^^^^^^^^ not FFI-safe | note: the lint level is defined here --> tests/test_ffi.rs:1:26 | 1 | #![warn(improper_ctypes, improper_ctypes_definitions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout warning: `extern` fn uses type `Option`, which is not FFI-safe --> tests/test_ffi.rs:16:32 | 16 | pub extern "C" fn anyhow3() -> Option { | ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint --- tests/test_ffi.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/test_ffi.rs diff --git a/tests/test_ffi.rs b/tests/test_ffi.rs new file mode 100644 index 0000000..88bfc97 --- /dev/null +++ b/tests/test_ffi.rs @@ -0,0 +1,18 @@ +#![warn(improper_ctypes, improper_ctypes_definitions)] + +use anyhow::anyhow; + +#[no_mangle] +pub extern "C" fn anyhow1(err: anyhow::Error) { + println!("{:?}", err); +} + +#[no_mangle] +pub extern "C" fn anyhow2(err: &mut Option) { + *err = Some(anyhow!("ffi error")); +} + +#[no_mangle] +pub extern "C" fn anyhow3() -> Option { + Some(anyhow!("ffi error")) +} From 3105a739d97042f3f831c24b10e4baab16f819b4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 18 Dec 2020 12:16:54 -0800 Subject: [PATCH 2/2] Mark Error repr transparent --- src/lib.rs | 1 + tests/test_ffi.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index a211b22..d124b1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -361,6 +361,7 @@ pub use anyhow as format_err; /// # Ok(()) /// } /// ``` +#[repr(transparent)] pub struct Error { inner: ManuallyDrop>>, } diff --git a/tests/test_ffi.rs b/tests/test_ffi.rs index 88bfc97..0321fc1 100644 --- a/tests/test_ffi.rs +++ b/tests/test_ffi.rs @@ -1,4 +1,4 @@ -#![warn(improper_ctypes, improper_ctypes_definitions)] +#![deny(improper_ctypes, improper_ctypes_definitions)] use anyhow::anyhow;