I am wrapping some Rust code into C FFI and I got code roughly like this:
pub struct Foo { ... }
impl Foo {
fn new() -> Self { ... }
fn consume(self) -> u32 { ... }
}
impl Drop for Foo {
fn drop(&mut self) { ... }
}
#[no_mangle]
pub unsafe extern "C" fn foo_new(foo: *mut Foo) {
*foo = Foo::new();
}
#[no_mangle]
pub unsafe extern "C" fn foo_consume(foo: *mut Foo) -> u32 {
core::ptr::read(foo).consume()
}
Obviously, the foo_consume
method is not ideal. Not only it's inefficient (compiler can not optimize the read, since data behind the input pointer is considered potentially observable), but also may cause security issues if the drop implementation involves secure erasure of sensitive information (e.g. cryptographic keys).
Is it possible to somehow call a consuming method on a raw pointer? For large enough structs compiler generates code which passes self
via pointer, so ABI-wise it can be compatible. If not, would it be reasonable to add something like intrinsic for it to the language?