mozilla / cbindgen

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

Handle constants of nested transparent types #958

Closed scovich closed 1 month ago

scovich commented 1 month ago

When defining a constant of multiply-nested transparent struct type, the struct is reduced to typedefs and so the extra layers of constant initializer need to be removed. The existing code only removed one layer. Fixed by changing the check to a loop.

Without the fix, a declaration like this:

#[repr(transparent)]
struct TransparentStruct { field: u8 }

#[repr(transparent)]
struct Foo<T> { field: T }

#[repr(transparent)]
struct Bar<T> {
    field: Foo<T>,
}

pub const BAR: Bar<TransparentStruct> =
    Bar { field: Foo { field: TransparentStruct { field: 7 } } };

exports as

constexpr static const Bar<TransparentStruct> BAR =
    Foo { /* .field = */ TransparentStruct{ /* .field = */ 7 } };

instead of the desired

constexpr static const Bar<TransparentStruct> BAR = 7;