mozilla / cbindgen

A project for generating C bindings from Rust code
Mozilla Public License 2.0
2.39k stars 307 forks source link

Generate error when `#[repr(C)]` types contain non-`#[repr(C)]` types #132

Open hfiguiere opened 6 years ago

hfiguiere commented 6 years ago

The following code:

#[repr(C)]
pub enum PropertyValue {
    String(String),
    Int(i64)
}

#[no_mangle]
pub extern "C" fn get_int(value: &PropertyValue) -> i64 {
    match value {
        Int(i) => i,
        _ => 0
    }
}

generates invalid C/C++ code with cbindgen. The problem lies in:

struct String;

struct PropertyValue {
  enum class Tag {
    String,
    Int,
  };

  struct String_Body {
    String _0;
  };

String is declared as opaque, but then used as if it wasn't.

I'm not sure what the proper solution would be short of ignoring the enum altogether.

hfiguiere commented 6 years ago

Removing the #[repr(C)] works around the problem in my case.

eqrion commented 6 years ago

The problem here is that we don't do an analysis on #[repr(C)] types to see if they actually contain only #[repr(C)] types. We should add one, and drop any #[repr(C)] types that don't pass with a warning.