You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It looks like this opaque type leaves me no way to redefine the binding in the header, or work around otherwise. Is there anything we could to do make this work?
We need to confer with the Rust devs to verify that Option<NonZeroU64> actually has the Integer type kind in rustc's ABI lowering (naively it is an Aggregate), and that this is guaranteed. As is, the libs docs only guarantee that it has the same size.
It's also non-obvious that lowering this to a raw u64 is good API ergonomics, but if that's the ABI it has there's not much else we can do, since aiui C++ doesn't have repr(transparent) for us to wrap up the value with.
Can we invite them here? Or are you in any of the WGs that may raise this question on a call?
For some context, this is needed for WebGPU, where Google's native implementation identifies objects by pointers, and ours - by these Id things that are transparently non-zero u64. What we'd like to have is a nullable semantics on the C API side.
The Option<NonZero> optimization that cbindgen has is very local / naive. If you were using Option<NonZeroU64> we could simplify it away to u64 very easily.
But having an extra type in the middle complicates it a bit more. This is an issue for the existing code already:
pubtypeStaticRef = &'statici32;#[repr(C)]pubstructFoo{a:Option<StaticRef>,// Doesn't work b:Option<&'statici32>,// works }#[no_mangle]pubextern"C"fnroot(f:Foo){}
This all can be fixed of course, it's just quite a bit of error-prone work.
That being said. For C++, your test-case generates Option<Bar> which you can specialize.
For C, you can do struct Option_Foo { uint64_t id; } right? This seems to build:
And you can trivially add an include with that definition. Passing Option_Foo by value on functions may not work / be guaranteed (that's @Gankra's concern), but I think you can pretty easily do this. Or am I missing something @kvark?
That being said, I would've expected:
[export]
exclude = [
"Option_Foo"
]
To do what you want, but right now it doesn't happen because we remove the excluded types before instantiating the monomorph types for C. So I think that could work if you needed by moving the remove_excluded() call a bit later:
oh fwiw i have verified that Option<NonZero*> should ~incidentally have the bare integer ABI, but it's not strictly written down to be guaranteed. I would be comfortable relying on it with a handshake agreement with the compiler devs to not break it.
Activity
kvark commentedon Mar 31, 2020
@emilio @Gankra could you post your thoughts on that?
Gankra commentedon Mar 31, 2020
We need to confer with the Rust devs to verify that
Option<NonZeroU64>actually has the Integer type kind in rustc's ABI lowering (naively it is an Aggregate), and that this is guaranteed. As is, the libs docs only guarantee that it has the same size.It's also non-obvious that lowering this to a raw u64 is good API ergonomics, but if that's the ABI it has there's not much else we can do, since aiui C++ doesn't have
repr(transparent)for us to wrap up the value with.kvark commentedon Mar 31, 2020
Can we invite them here? Or are you in any of the WGs that may raise this question on a call?
For some context, this is needed for WebGPU, where Google's native implementation identifies objects by pointers, and ours - by these
Idthings that are transparently non-zerou64. What we'd like to have is a nullable semantics on the C API side.emilio commentedon Mar 31, 2020
The
Option<NonZero>optimization that cbindgen has is very local / naive. If you were usingOption<NonZeroU64>we could simplify it away to u64 very easily.But having an extra type in the middle complicates it a bit more. This is an issue for the existing code already:
This all can be fixed of course, it's just quite a bit of error-prone work.
That being said. For C++, your test-case generates
Option<Bar>which you can specialize.For C, you can do
struct Option_Foo { uint64_t id; }right? This seems to build:And you can trivially add an include with that definition. Passing
Option_Fooby value on functions may not work / be guaranteed (that's @Gankra's concern), but I think you can pretty easily do this. Or am I missing something @kvark?That being said, I would've expected:
To do what you want, but right now it doesn't happen because we remove the excluded types before instantiating the monomorph types for C. So I think that could work if you needed by moving the
remove_excluded()call a bit later:https://github.com/eqrion/cbindgen/blob/723e690027209c8e613c729def6a9367e197b00f/src/bindgen/library.rs#L57-L69
kvark commentedon Mar 31, 2020
Oh great, that workaround should do it for us, thanks!
Edit: actually, not just yet. Having
struct Option_Foo { uint64_t maybe_id; };on the C side is not what we need.Allow excluding monomorph structs in C mode.
Allow excluding monomorph structs in C mode.
Merge #546
Merge #546
Gankra commentedon Apr 15, 2020
oh fwiw i have verified that
Option<NonZero*>should ~incidentally have the bare integer ABI, but it's not strictly written down to be guaranteed. I would be comfortable relying on it with a handshake agreement with the compiler devs to not break it.Gankra commentedon Apr 16, 2020
correction: super guaranteed and intentional: https://github.com/rust-lang/rust/blob/master/src/libcore/num/mod.rs#L62