crabtw/rust-bindgen — pull request #86 by SiegeLord (2014-06-01 00:12:53+00:00)
Title: Bind opaque C types as empty enums.

C declarations such as this:
~~~c
typedef struct A A;
typedef union B B;
typedef enum C C;
~~~
Are currently bound by bindgen like so:
~~~rust
pub type Struct_A = c_void;
pub type A = Struct_A;
pub type Union_B = c_void;
pub type B = Union_B;
pub type C = Enum_C;
pub type Enum_C = c_void;
~~~
This is problematic, because you can construct these types by value and also use them interchangeably, e.g. this works even though it is clearly a bug:
~~~rust
unsafe {
let a: A = libc::types::common::c95::__variant1;
let b: B = a;
let ap: *A = std::ptr::null();
let bp: *B = ap;
}
~~~

With this change, the C opaque types are bound as empty Rust enums:

~~~rust
pub enum Struct_A { }
pub type A = Struct_A;
pub enum Union_B { }
pub type B = Union_B;
pub type C = Enum_C;
pub enum Enum_C { }
~~~

The Rust code above no longer compiles (and you can't even construct them on the stack anymore outside of unsafe code):

~~~
test.rs:26:22: 26:24 error: mismatched types: expected `*Union_B` but found `*Struct_A` (expected enum Union_B but found enum Struct_A)
test.rs:26 let bp: *B = ap;
~~~