Code
#![allow(unused)]
#[link(name = "my_c_library")]
unsafe extern "C" {
fn my_c_function_1(x: Box<i32>);
fn my_c_function_2(x: i32) -> Box<String>;
fn my_c_function_3(x: &mut Box<[u8]>);
}
Current output
warning: `extern` block uses type `Box<i32>`, which is not FFI-safe
--> src/lib.rs:6:27
|
6 | fn my_c_function_1(x: Box<i32>);
| ^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
= note: `#[warn(improper_ctypes)]` on by default
warning: `extern` block uses type `Box<String>`, which is not FFI-safe
--> src/lib.rs:7:35
|
7 | fn my_c_function_2(x: i32) -> Box<String>;
| ^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
warning: `extern` block uses type `Box<[u8]>`, which is not FFI-safe
--> src/lib.rs:8:27
|
8 | fn my_c_function_3(x: &mut Box<[u8]>);
| ^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
Desired output
warning: `extern` block uses type `String`, which is not FFI-safe
--> src/lib.rs:8:35
|
8 | fn my_c_function_2(x: i32) -> Box<String>;
| ^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
= note: `#[warn(improper_ctypes)]` on by default
warning: `extern` block uses type `[u8]`, which is not FFI-safe
--> src/lib.rs:9:27
|
9 | fn my_c_function_3(x: &mut Box<[u8]>);
| ^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider using a raw pointer instead
= note: slices have no C equivalent
Rationale and extra context
Box is FFI safe, as promised by its documentation https://doc.rust-lang.org/std/boxed/index.html#memory-layout.
its use may be dangerous, as it must always be aligned, nonnull, has strict aliasing rules, and must be allocated and deallocated in rust, but it can still be very useful in well crafted APIs.
having improper_ctypes trigger on it forces users who use it to add allow/expect(improper_ctypes), preventing them from seeing other improper_ctypes behind the indirection.
thus i believe Box should be special-cased to have improper_ctypes not trigger on it directly.
i believe it should behave the exact same way as other pointers do(*mut/*const/NonNull/&/&mut).
note that this should only apply for Box<T,GLobal>, as no guarantees are made about other allocators, especially if they are not 1-aligned ZSTs
link to a forum post where a user ran into this exact issue https://users.rust-lang.org/t/ffi-safety-of-box-t/39156
on the note of the danger posed by the many safety and validity invariants of Box, i would like to note that &mut shares many of them, and does not trigger improper_ctypes. as it should given it is layout compatible.
Rust Version
rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-pc-windows-msvc
release: 1.92.0
LLVM version: 21.1.3
Code
Current output
Desired output
Rationale and extra context
Boxis FFI safe, as promised by its documentation https://doc.rust-lang.org/std/boxed/index.html#memory-layout.its use may be dangerous, as it must always be aligned, nonnull, has strict aliasing rules, and must be allocated and deallocated in rust, but it can still be very useful in well crafted APIs.
having
improper_ctypestrigger on it forces users who use it to addallow/expect(improper_ctypes), preventing them from seeing otherimproper_ctypesbehind the indirection.thus i believe
Boxshould be special-cased to haveimproper_ctypesnot trigger on it directly.i believe it should behave the exact same way as other pointers do(*mut/*const/NonNull/&/&mut).
note that this should only apply for
Box<T,GLobal>, as no guarantees are made about other allocators, especially if they are not 1-aligned ZSTslink to a forum post where a user ran into this exact issue https://users.rust-lang.org/t/ffi-safety-of-box-t/39156
on the note of the danger posed by the many safety and validity invariants of
Box, i would like to note that&mutshares many of them, and does not triggerimproper_ctypes. as it should given it is layout compatible.Rust Version