cbindgen/tests/rust/nonnull.rs
Emilio Cobos Álvarez 5ac196d3ef ty: Add support for simplifying NonNull<T>.
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) {}
```
2018-10-17 09:24:22 -05:00

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>>) { }