I want this to move around slices and boxes across the style system, while preserving the option size optimizations when they're fully in a repr(Rust) data-structure. This is sound because NonNull is repr(transparent): https://doc.rust-lang.org/src/core/ptr.rs.html#2847 I renamed simplify_option_to_ptr to simplify_standard_types because that's what it does now. ABI-wise for NonNull<T> it's guaranteed via repr(transparent). For Option<NonNull<T>> it is as well, though I've asked in #rustc to confirm. The LLVM IR of: ``` pub extern "C" fn foo(ptr: Option<::std::ptr::NonNull<i32>>) {} ``` is: ``` define void @foo(i32*) unnamed_addr #0 !dbg !310 { start: %ptr = alloca i32*, align 8 store i32* %0, i32** %ptr, align 8 call void @llvm.dbg.declare(metadata i32** %ptr, metadata !327, metadata !DIExpression()), !dbg !328 ret void, !dbg !329 } ``` Which is the same as for: ``` pub extern "C" fn foo(ptr: ::std::ptr::NonNull<i32>) {} ``` Except without the nonnull annotation. And the same as for: ``` pub extern "C" fn foo(ptr: *mut i32) {} ```
20 lines
431 B
Rust
20 lines
431 B
Rust
use std::ptr::NonNull;
|
|
|
|
struct Opaque;
|
|
|
|
#[repr(C)]
|
|
pub struct Foo<T> {
|
|
a: NonNull<f32>,
|
|
b: NonNull<T>,
|
|
c: NonNull<Opaque>,
|
|
d: NonNull<NonNull<T>>,
|
|
e: NonNull<NonNull<f32>>,
|
|
f: NonNull<NonNull<Opaque>>,
|
|
g: Option<NonNull<T>>,
|
|
h: Option<NonNull<i32>>,
|
|
i: Option<NonNull<NonNull<i32>>>,
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn root(arg: NonNull<i32>, foo: *mut Foo<u64>, d: NonNull<NonNull<Opaque>>) { }
|