Rust-bindgen: the trait bound `[u8; 44]: std::default::Default` is not satisfied

Created on 1 Feb 2020  路  6Comments  路  Source: rust-lang/rust-bindgen

I change the bindgen version from 0.30.0 to 0.52.0 in nginx crate.

Header

#include <ngx_http.h>

Bindgen Invocation

let bindings = bindgen::Builder::default()
        .derive_debug(false)
        .header("wrapper.h")
        .layout_tests(false)
        .clang_args(vec![
            format!("-I{}/src/core", nginx_dir),
            format!("-I{}/src/event", nginx_dir),
            format!("-I{}/src/event/modules", nginx_dir),
            format!("-I{}/src/os/unix", nginx_dir),
            format!("-I{}/objs", nginx_dir),
            format!("-I{}/src/http", nginx_dir),
            format!("-I{}/src/http/v2", nginx_dir),
            format!("-I{}/src/http/modules", nginx_dir),
        ])
        .generate()
        .expect("Unable to generate bindings");

Actual Results

error[E0277]: the trait bound `[u8; 44]: std::default::Default` is not satisfied
     --> /module/target/release/build/nginx-96f1184c07e3304c/out/bindings.rs:19021:13
      |
19021 |             Default::default();
      |             ^^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `[u8; 44]`
      |
      = help: the following implementations were found:
                <&[T] as std::default::Default>
                <&mut [T] as std::default::Default>
                <[T; 0] as std::default::Default>
                <[T; 10] as std::default::Default>
              and 31 others
      = note: required because of the requirements on the impl of `std::default::Default` for `bindings::__BindgenBitfieldUnit<[u8; 44], u8>`
      = note: required by `std::default::Default::default`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `nginx`.

Expected Results

The crate is successfully built using v0.30.0 of bindgen, however an update to bindgen version causes the problem. I tried derive_default(true) with no success.

A-bitfields bug help wanted

Most helpful comment

also, one could hope that rust would get const generics one of these days, so we can stop hacking around the 32-bit size limit in arrays... ;(

All 6 comments

How does the struct look like? This should be pretty easy to reduce.

Ok, so at least on my machine that looks like this:

/*
 * syscall interface - used (mainly by NTP daemon)
 * to discipline kernel clock oscillator
 */
struct timex {
    unsigned int modes; /* mode selector */
    __kernel_long_t offset; /* time offset (usec) */
    __kernel_long_t freq;   /* frequency offset (scaled ppm) */
    __kernel_long_t maxerror;/* maximum error (usec) */
    __kernel_long_t esterror;/* estimated error (usec) */
    int status;     /* clock command/status */
    __kernel_long_t constant;/* pll time constant */
    __kernel_long_t precision;/* clock precision (usec) (read only) */
    __kernel_long_t tolerance;/* clock frequency tolerance (ppm)
                   * (read only)
                   */
    struct timeval time;    /* (read only, except for ADJ_SETOFFSET) */
    __kernel_long_t tick;   /* (modified) usecs between clock ticks */

    __kernel_long_t ppsfreq;/* pps frequency (scaled ppm) (ro) */
    __kernel_long_t jitter; /* pps jitter (us) (ro) */
    int shift;              /* interval duration (s) (shift) (ro) */
    __kernel_long_t stabil;            /* pps stability (scaled ppm) (ro) */
    __kernel_long_t jitcnt; /* jitter limit exceeded (ro) */
    __kernel_long_t calcnt; /* calibration intervals (ro) */
    __kernel_long_t errcnt; /* calibration errors (ro) */
    __kernel_long_t stbcnt; /* stability limit exceeded (ro) */

    int tai;        /* TAI offset (ro) */

    int  :32; int  :32; int  :32; int  :32;
    int  :32; int  :32; int  :32; int  :32;
    int  :32; int  :32; int  :32;
};

Does that match your machine?

Ok, so this does repro the issue:

struct timex {
    int tai;

    int  :32; int  :32; int  :32; int  :32;
    int  :32; int  :32; int  :32; int  :32;
    int  :32; int  :32; int  :32;
};

A workaround for now could be to blacklist / mark timex as opaque. But this is a bindgen bug clearly.

I opaqued timex and it is built now

also, one could hope that rust would get const generics one of these days, so we can stop hacking around the 32-bit size limit in arrays... ;(

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fpagliughi picture fpagliughi  路  9Comments

jrmuizel picture jrmuizel  路  9Comments

bbigras picture bbigras  路  3Comments

maurer picture maurer  路  3Comments

Stargateur picture Stargateur  路  9Comments