Skip to content

error[E0588]: packed type cannot transitively contain a #[repr(align)] type #102733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
olivier-fs opened this issue Oct 6, 2022 · 3 comments
Closed

Comments

@olivier-fs
Copy link

olivier-fs commented Oct 6, 2022

Hi!

I'm trying to build the bindgen tutorial example from :
https://rust-lang.github.io/rust-bindgen/tutorial-0.html
=> https://github.com/fitzgen/bindgen-tutorial-bzip2-sys
=> https://fitzgeraldnick.com/2016/12/14/using-libbindgen-in-build-rs.html

It's an exemple binding to bzip2 (just as an exemple ; the author knows about bzip2 and bzip2-sys crates).

I'm using :

  • rustc 1.64.0 (a55dd71 2022-09-19)
  • bindgen-0.60.1
  • LLVM-15.0.1 (clang version 15.0.1, Target: x86_64-pc-windows-msvc, InstalledDir: C:\dev\llvm-15.0.1\bin)
  • Windows 10
  • MSYS2/Mingw64 : clang64/mingw-w64-clang-x86_64-bzip2 1.0.8-2 as the provider of C package bzip2

After adding some bindgen::Builder config in build.rs to set path to included <bzlib.h> :

.clang_arg("-IC:/dev/msys64/clang64/include")

I'm getting this error :

$ cargo build
   Compiling bindgen-tutorial-bzip2-sys v0.1.0 (C:\Users\olivier\dev\rust\www-sample\interop\c\bindgen-tutorial-bzip2-sys)
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
     --> C:\Users\olivier\dev\rust\www-sample\interop\c\bindgen-tutorial-bzip2-sys\target\debug\build\bindgen-tutorial-bzip2-sys-03a76bb986e88418\out/bind

ings.rs:64916:1
      |
64916 | pub struct _IMAGE_TLS_DIRECTORY64 {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
note: `_IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1` has a `#[repr(align)]` attribute
     --> C:\Users\olivier\dev\rust\www-sample\interop\c\bindgen-tutorial-bzip2-sys\target\debug\build\bindgen-tutorial-bzip2-sys-03a76bb986e88418\out/bind

ings.rs:64933:1
      |
64933 | pub struct _IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1 {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `_IMAGE_TLS_DIRECTORY64` contains a field of type `_IMAGE_TLS_DIRECTORY64__bindgen_ty_1`
     --> C:\Users\olivier\dev\rust\www-sample\interop\c\bindgen-tutorial-bzip2-sys\target\debug\build\bindgen-tutorial-bzip2-sys-03a76bb986e88418\out/bind

ings.rs:64922:9
      |
64922 |     pub __bindgen_anon_1: _IMAGE_TLS_DIRECTORY64__bindgen_ty_1,
      |         ^^^^^^^^^^^^^^^^
note: ...which contains a field of type `_IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1`
     --> C:\Users\olivier\dev\rust\www-sample\interop\c\bindgen-tutorial-bzip2-sys\target\debug\build\bindgen-tutorial-bzip2-sys-03a76bb986e88418\out/bind

ings.rs:64928:9
      |
64928 |     pub __bindgen_anon_1: _IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1,
      |         ^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0588`.
error: could not compile `bindgen-tutorial-bzip2-sys` due to previous error

I tried with nightly toolchain (currently 1.66.0)

  • with cargo +nightly build
  • by adding some bindgen::Builder config in build.rs : .rust_target(bindgen::RustTarget::Nightly)
    but I get the same error.

I see that issue #67383 with the same problem has been closed.

  • Is rustc complain valid (i.e. bindgen has generated some "invalid" code), or is rustc hitting an error despite of valid bingen output ?
  • Is this error anyway related to rust/rustc, or should I forward the issue to bindgen ?
  • Otherwise, what to do to solve this, as I tried with latest stable rust and bindgen versions ?
@olivier-fs
Copy link
Author

Excerpt from bindgen generated bindings.rs :

#[repr(C, packed(4))]
#[derive(Copy, Clone)]
pub struct _IMAGE_TLS_DIRECTORY64 {
    pub StartAddressOfRawData: ULONGLONG,
    pub EndAddressOfRawData: ULONGLONG,
    pub AddressOfIndex: ULONGLONG,
    pub AddressOfCallBacks: ULONGLONG,
    pub SizeOfZeroFill: DWORD,
    pub __bindgen_anon_1: _IMAGE_TLS_DIRECTORY64__bindgen_ty_1,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union _IMAGE_TLS_DIRECTORY64__bindgen_ty_1 {
    pub Characteristics: DWORD,
    pub __bindgen_anon_1: _IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1,
}
#[repr(C)]
#[repr(align(4))]   /* <=== THIS LINE */
#[derive(Debug, Copy, Clone)]
pub struct _IMAGE_TLS_DIRECTORY64__bindgen_ty_1__bindgen_ty_1 {
    pub _bitfield_align_1: [u32; 0],
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>,
}

So these are nested struct, and rustc complains about the repr(align(4)) of the innermost struct, when the outer struct has repr(pack(4)).

Can someone with better understanding than I have of this packed vs align conflict confirm that rustc is rightfully raising an error ? I would then forward the issue to the bindgen crate.

Or is that a rustc error ?

@asquared31415
Copy link
Contributor

This is intended behavior as described by The Reference

a packed type cannot transitively contain another aligned type.

bindgen's code is very strange here, is it emitting both a repr(align) attribute and a dummy align field, at most one of those should be necessary.

@olivier-fs
Copy link
Author

Very clear now, this is an issue with the bindgen generated code ; and it's even not a matter of relative values of the packed/align parameters.
As always, machine-generated code looks strange/non-optimal for humans ; but bindgen spares a lot of hassle of doing manual bindings.
I guess this section of code is the result of a different bindgen code path than the one fixed in the other issue.
I'll forward the issue to rust-lang/rust-bindgen.
I close this issue.
Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants