Skip to content

Unions are generated with fields that are not Copy #895

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
tmfink opened this issue Aug 7, 2017 · 6 comments
Closed

Unions are generated with fields that are not Copy #895

tmfink opened this issue Aug 7, 2017 · 6 comments

Comments

@tmfink
Copy link
Contributor

tmfink commented Aug 7, 2017

Input C/C++ Header

template<class _CharT, class _Traits, class _Allocator>
class basic_string
{
public:
    typedef unsigned long long size_type;
    typedef char value_type;
    typedef value_type * pointer;

    struct __long
    {
        size_type __cap_;
        size_type __size_;
        pointer   __data_;
    };

    enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
                        (sizeof(__long) - 1)/sizeof(value_type) : 2};

    struct __short
    {
        union
        {
            unsigned char __size_;
            value_type __lx;
        };
        value_type __data_[__min_cap];
    };

    union __ulx{__long __lx; __short __lxx;};

    enum {__n_words = sizeof(__ulx) / sizeof(size_type)};

    struct __raw
    {
        size_type __words[__n_words];
    };

    struct __rep
    {
        union
        {
            __long  __l;
            __short __s;
            __raw   __r;
        };
    };
};

Bindgen Invocation

$ bindgen input.hpp --unstable-rust

Actual Results

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct basic_string {
    pub _address: u8,
}
pub type basic_string_size_type = ::std::os::raw::c_ulonglong;
pub type basic_string_value_type = ::std::os::raw::c_char;
pub type basic_string_pointer = *mut basic_string_value_type;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct basic_string___long {
    pub __cap_: basic_string_size_type,
    pub __size_: basic_string_size_type,
    pub __data_: basic_string_pointer,
}
pub const basic_string___min_cap: basic_string__bindgen_ty_1 =
    basic_string__bindgen_ty_1::__min_cap;
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum basic_string__bindgen_ty_1 { __min_cap = 0, }
#[repr(C)]
pub struct basic_string___short {
    pub __bindgen_anon_1: basic_string___short__bindgen_ty_1,
    pub __data_: *mut basic_string_value_type,
}
#[repr(C)]
pub union basic_string___short__bindgen_ty_1 {
    pub __size_: ::std::os::raw::c_uchar,
    pub __lx: basic_string_value_type,
}
#[repr(C)]
pub union basic_string___ulx {
    pub __lx: basic_string___long,
    pub __lxx: basic_string___short,
}
pub const basic_string___n_words: basic_string__bindgen_ty_2 =
    basic_string__bindgen_ty_2::__n_words;
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum basic_string__bindgen_ty_2 { __n_words = 0, }
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct basic_string___raw {
    pub __words: *mut basic_string_size_type,
}
#[repr(C)]
pub struct basic_string___rep {
    pub __bindgen_anon_1: basic_string___rep__bindgen_ty_1,
}
#[repr(C)]
pub union basic_string___rep__bindgen_ty_1 {
    pub __l: basic_string___long,
    pub __s: basic_string___short,
    pub __r: basic_string___raw,
}

Attempting to compile with rustc with stable 1.19 or nightly (1.21.0-nightly (ed16b0a1d 2017-08-05)) gives:

error: unions with non-`Copy` fields are unstable (see issue #32836)
  --> test.rs:34:1
   |
34 | / pub union basic_string___ulx {
35 | |     pub __lx: basic_string___long,
36 | |     pub __lxx: basic_string___short,
37 | | }
   | |_^

error: unions with non-`Copy` fields are unstable (see issue #32836)
  --> test.rs:53:1
   |
53 | / pub union basic_string___rep__bindgen_ty_1 {
54 | |     pub __l: basic_string___long,
55 | |     pub __s: basic_string___short,
56 | |     pub __r: basic_string___raw,
57 | | }
   | |_^

Expected Results

No compilation failure

@tmfink
Copy link
Contributor Author

tmfink commented Aug 8, 2017

@photoszzt made a comment in PR #892:

I think the problem is for the field cannot derive Copy the behavior is not standardized. You would need to add the feature gate in the header. @fitzgen maybe fall back to generate the BingenUnion when the field cannot be Copy?

@fitzgen
Copy link
Member

fitzgen commented Aug 8, 2017

Thanks for tracking this down!

I think @photoszzt has it correct: we should only emit unions for stable rust targets when all of the fields are Copy. For nightly rust targets, we can emit them regardless.

@photoszzt
Copy link
Contributor

For stable rust, it's generating BindgenUnion. We need to also generate the feature gate in the nightly target.

@fitzgen
Copy link
Member

fitzgen commented Aug 8, 2017

For stable rust, it's generating BindgenUnion.

Depends on which stable rust after #892 ;)

We need to also generate the feature gate in the nightly target.

We never generate the #![feature(..)] attributes ourselves, because the bindings aren't usually at the top level of the crate. Authors need to do it themselves.

Our test suite would need to generate them, however. But we don't even currently test on nightly rust, so we would need to start doing that, and also have a nightly feature so that we could skip these tests on stable rust.

@photoszzt
Copy link
Contributor

We can add the #![feature(...)] in lib.rs under expectations dir.

tmfink added a commit to tmfink/rust-bindgen that referenced this issue Aug 12, 2017
@pvdrz
Copy link
Contributor

pvdrz commented Sep 19, 2022

This compiles successfully with rust 1.57 which is the minimum supported version

@pvdrz pvdrz closed this as completed Sep 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants