Skip to content

Nested packed struct containing incomplete array declaration results in compilation failure due to non-present Debug impl #3341

@rlee287

Description

@rlee287

example.h:

struct nested_struct {
  char *name;
  unsigned char more_data[];
} __attribute__((packed));

struct {
  struct nested_struct meow;
} cat;

After running bindgen -o example.rs example.h, we get

/* automatically generated by rust-bindgen 0.72.1 */

#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
    #[inline]
    pub const fn new() -> Self {
        __IncompleteArrayField(::std::marker::PhantomData, [])
    }
    #[inline]
    pub fn as_ptr(&self) -> *const T {
        self as *const _ as *const T
    }
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T {
        self as *mut _ as *mut T
    }
    #[inline]
    pub unsafe fn as_slice(&self, len: usize) -> &[T] {
        ::std::slice::from_raw_parts(self.as_ptr(), len)
    }
    #[inline]
    pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
        ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
    }
}
impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_str("__IncompleteArrayField")
    }
}
#[repr(C, packed)]
pub struct nested_struct {
    pub name: *mut ::std::os::raw::c_char,
    pub more_data: __IncompleteArrayField<::std::os::raw::c_uchar>,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of nested_struct"][::std::mem::size_of::<nested_struct>() - 8usize];
    ["Alignment of nested_struct"][::std::mem::align_of::<nested_struct>() - 1usize];
    ["Offset of field: nested_struct::name"][::std::mem::offset_of!(nested_struct, name) - 0usize];
    ["Offset of field: nested_struct::more_data"]
        [::std::mem::offset_of!(nested_struct, more_data) - 8usize];
};
#[repr(C)]
#[derive(Debug)]
pub struct _bindgen_ty_1 {
    pub meow: nested_struct,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of _bindgen_ty_1"][::std::mem::size_of::<_bindgen_ty_1>() - 8usize];
    ["Alignment of _bindgen_ty_1"][::std::mem::align_of::<_bindgen_ty_1>() - 1usize];
    ["Offset of field: _bindgen_ty_1::meow"][::std::mem::offset_of!(_bindgen_ty_1, meow) - 0usize];
};
unsafe extern "C" {
    pub static mut cat: _bindgen_ty_1;
}

Trying to compile example.rs with rustc --crate-type staticlib -A nonstandard_style example.rs produces

error[E0277]: `nested_struct` doesn't implement `Debug`
  --> example_manual.rs:49:5
   |
47 | #[derive(Debug)]
   |          ----- in this derive macro expansion
48 | pub struct _bindgen_ty_1 {
49 |     pub meow: nested_struct,
   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `nested_struct`
   |
   = note: add `#[derive(Debug)]` to `nested_struct` or manually `impl Debug for nested_struct`
help: consider annotating `nested_struct` with `#[derive(Debug)]`
   |
34 + #[derive(Debug)]
35 | pub struct nested_struct {
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.

It seems like the combination of the incomplete array field and the struct nesting results in a #[derive(Debug)] line being incorrectly generated for the anonymous struct even though nested_struct lacks it.

Tested with bindgen 0.72.1 and master (74a5f30 as of the time of writing) using Rust 1.93

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions