Skip to content

the trait bound [u8; 44]: std::default::Default is not satisfied #1718

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
yaa110 opened this issue Feb 1, 2020 · 7 comments · Fixed by #1719
Closed

the trait bound [u8; 44]: std::default::Default is not satisfied #1718

yaa110 opened this issue Feb 1, 2020 · 7 comments · Fixed by #1719

Comments

@yaa110
Copy link

yaa110 commented Feb 1, 2020

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.

@emilio
Copy link
Contributor

emilio commented Feb 1, 2020

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

@oghaffarinia
Copy link

The error arises for timex struct from linux headers
This is what is produced using bindgen:

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timex {
    pub modes: ::std::os::raw::c_uint,
    pub offset: __syscall_slong_t,
    pub freq: __syscall_slong_t,
    pub maxerror: __syscall_slong_t,
    pub esterror: __syscall_slong_t,
    pub status: ::std::os::raw::c_int,
    pub constant: __syscall_slong_t,
    pub precision: __syscall_slong_t,
    pub tolerance: __syscall_slong_t,
    pub time: timeval,
    pub tick: __syscall_slong_t,
    pub ppsfreq: __syscall_slong_t,
    pub jitter: __syscall_slong_t,
    pub shift: ::std::os::raw::c_int,
    pub stabil: __syscall_slong_t,
    pub jitcnt: __syscall_slong_t,
    pub calcnt: __syscall_slong_t,
    pub errcnt: __syscall_slong_t,
    pub stbcnt: __syscall_slong_t,
    pub tai: ::std::os::raw::c_int,
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize], u8>,
}
impl timex {
    #[inline]
    pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 44usize], u8> {
        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 44usize], u8> =
            Default::default();
        __bindgen_bitfield_unit
    }
}

@emilio
Copy link
Contributor

emilio commented Feb 2, 2020

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?

@emilio
Copy link
Contributor

emilio commented Feb 2, 2020

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.

@yaa110
Copy link
Author

yaa110 commented Feb 2, 2020

I opaqued timex and it is built now

emilio added a commit to emilio/rust-bindgen that referenced this issue Feb 2, 2020
By not generating various code for it.

In the future, we could improve on this by splitting contiguous bitfield units,
if needed, so that we can implement them without dealing with rust array derive
limits.

Fixes rust-lang#1718
@emilio
Copy link
Contributor

emilio commented Feb 2, 2020

#1719 has a fix.

@emilio
Copy link
Contributor

emilio commented Feb 2, 2020

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... ;(

emilio added a commit that referenced this issue Feb 2, 2020
By not generating various code for it.

In the future, we could improve on this by splitting contiguous bitfield units,
if needed, so that we can implement them without dealing with rust array derive
limits.

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

Successfully merging a pull request may close this issue.

3 participants