Skip to content

Commit

Permalink
Derive from any other trait only when deriving from Copy
Browse files Browse the repository at this point in the history
It's impossible to #[derive] from any other trait when not deriving from
Copy when using the newest Rust nightly. Any attempt to do that results
in the following error:

  error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)

Fixes: rust-lang#2083
Signed-off-by: Michal Rostecki <vadorovsky@gmail.com>
  • Loading branch information
vadorovsky committed May 4, 2022
1 parent ee6ff69 commit c8bc986
Show file tree
Hide file tree
Showing 41 changed files with 482 additions and 126 deletions.
49 changes: 25 additions & 24 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,6 @@ bitflags! {
fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
let mut derivable_traits = DerivableTraits::empty();

if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
derivable_traits |= DerivableTraits::DEBUG;
}

if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
derivable_traits |= DerivableTraits::DEFAULT;
}

let all_template_params = item.all_template_params(ctx);

if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
Expand All @@ -137,26 +129,36 @@ fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
// It's not hard to fix though.
derivable_traits |= DerivableTraits::CLONE;
}
}

if item.can_derive_hash(ctx) {
derivable_traits |= DerivableTraits::HASH;
}
if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
derivable_traits |= DerivableTraits::DEBUG;
}

if item.can_derive_partialord(ctx) {
derivable_traits |= DerivableTraits::PARTIAL_ORD;
}
if item.can_derive_default(ctx) &&
!item.annotations().disallow_default()
{
derivable_traits |= DerivableTraits::DEFAULT;
}

if item.can_derive_ord(ctx) {
derivable_traits |= DerivableTraits::ORD;
}
if item.can_derive_hash(ctx) {
derivable_traits |= DerivableTraits::HASH;
}

if item.can_derive_partialeq(ctx) {
derivable_traits |= DerivableTraits::PARTIAL_EQ;
}
if item.can_derive_partialord(ctx) {
derivable_traits |= DerivableTraits::PARTIAL_ORD;
}

if item.can_derive_eq(ctx) {
derivable_traits |= DerivableTraits::EQ;
if item.can_derive_ord(ctx) {
derivable_traits |= DerivableTraits::ORD;
}

if item.can_derive_partialeq(ctx) {
derivable_traits |= DerivableTraits::PARTIAL_EQ;
}

if item.can_derive_eq(ctx) {
derivable_traits |= DerivableTraits::EQ;
}
}

derivable_traits
Expand Down Expand Up @@ -4554,7 +4556,6 @@ pub mod utils {

let incomplete_array_decl = quote! {
#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(
::#prefix::marker::PhantomData<T>, [T; 0]);
};
Expand Down
20 changes: 18 additions & 2 deletions tests/expectations/tests/allowlisted_item_references_no_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
)]

#[repr(C)]
#[derive(Debug, Default)]
pub struct NoCopy {
pub _address: u8,
}
Expand All @@ -23,8 +22,16 @@ fn bindgen_test_layout_NoCopy() {
concat!("Alignment of ", stringify!(NoCopy))
);
}
impl Default for NoCopy {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct AllowlistMe {
pub a: NoCopy,
}
Expand Down Expand Up @@ -53,3 +60,12 @@ fn bindgen_test_layout_AllowlistMe() {
)
);
}
impl Default for AllowlistMe {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
40 changes: 36 additions & 4 deletions tests/expectations/tests/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
)]

#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
Expand Down Expand Up @@ -190,6 +189,15 @@ fn bindgen_test_layout_C_with_zero_length_array_2() {
)
);
}
impl Default for C_with_zero_length_array_2 {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
pub struct C_with_incomplete_array {
pub a: ::std::os::raw::c_int,
Expand Down Expand Up @@ -219,7 +227,6 @@ impl Default for C_with_incomplete_array {
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct C_with_incomplete_array_2 {
pub a: ::std::os::raw::c_int,
pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>,
Expand All @@ -237,6 +244,15 @@ fn bindgen_test_layout_C_with_incomplete_array_2() {
concat!("Alignment of ", stringify!(C_with_incomplete_array_2))
);
}
impl Default for C_with_incomplete_array_2 {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
pub struct C_with_zero_length_array_and_incomplete_array {
pub a: ::std::os::raw::c_int,
Expand Down Expand Up @@ -273,7 +289,6 @@ impl Default for C_with_zero_length_array_and_incomplete_array {
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct C_with_zero_length_array_and_incomplete_array_2 {
pub a: ::std::os::raw::c_int,
pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>,
Expand All @@ -300,8 +315,16 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() {
)
);
}
impl Default for C_with_zero_length_array_and_incomplete_array_2 {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
#[derive(Debug, Default, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct WithDtor {
pub b: ::std::os::raw::c_int,
}
Expand All @@ -328,6 +351,15 @@ fn bindgen_test_layout_WithDtor() {
)
);
}
impl Default for WithDtor {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
pub struct IncompleteArrayNonCopiable {
pub whatever: *mut ::std::os::raw::c_void,
Expand Down
41 changes: 36 additions & 5 deletions tests/expectations/tests/class_1_0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
)]

#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
Expand Down Expand Up @@ -199,7 +198,6 @@ impl Default for C_with_zero_length_array {
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct C_with_zero_length_array_2 {
pub a: ::std::os::raw::c_int,
pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>,
Expand Down Expand Up @@ -243,6 +241,15 @@ fn bindgen_test_layout_C_with_zero_length_array_2() {
)
);
}
impl Default for C_with_zero_length_array_2 {
fn default() -> Self {
unsafe {
let mut s: Self = ::std::mem::uninitialized();
::std::ptr::write_bytes(&mut s, 0, 1);
s
}
}
}
#[repr(C)]
pub struct C_with_incomplete_array {
pub a: ::std::os::raw::c_int,
Expand Down Expand Up @@ -272,7 +279,6 @@ impl Default for C_with_incomplete_array {
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct C_with_incomplete_array_2 {
pub a: ::std::os::raw::c_int,
pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>,
Expand All @@ -290,6 +296,15 @@ fn bindgen_test_layout_C_with_incomplete_array_2() {
concat!("Alignment of ", stringify!(C_with_incomplete_array_2))
);
}
impl Default for C_with_incomplete_array_2 {
fn default() -> Self {
unsafe {
let mut s: Self = ::std::mem::uninitialized();
::std::ptr::write_bytes(&mut s, 0, 1);
s
}
}
}
#[repr(C)]
pub struct C_with_zero_length_array_and_incomplete_array {
pub a: ::std::os::raw::c_int,
Expand Down Expand Up @@ -326,7 +341,6 @@ impl Default for C_with_zero_length_array_and_incomplete_array {
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct C_with_zero_length_array_and_incomplete_array_2 {
pub a: ::std::os::raw::c_int,
pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>,
Expand All @@ -353,8 +367,16 @@ fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array_2() {
)
);
}
impl Default for C_with_zero_length_array_and_incomplete_array_2 {
fn default() -> Self {
unsafe {
let mut s: Self = ::std::mem::uninitialized();
::std::ptr::write_bytes(&mut s, 0, 1);
s
}
}
}
#[repr(C)]
#[derive(Debug, Default, Hash, PartialEq, Eq)]
pub struct WithDtor {
pub b: ::std::os::raw::c_int,
}
Expand All @@ -381,6 +403,15 @@ fn bindgen_test_layout_WithDtor() {
)
);
}
impl Default for WithDtor {
fn default() -> Self {
unsafe {
let mut s: Self = ::std::mem::uninitialized();
::std::ptr::write_bytes(&mut s, 0, 1);
s
}
}
}
#[repr(C)]
pub struct IncompleteArrayNonCopiable {
pub whatever: *mut ::std::os::raw::c_void,
Expand Down
2 changes: 0 additions & 2 deletions tests/expectations/tests/class_with_dtor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
)]

#[repr(C)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct HandleWithDtor<T> {
pub ptr: *mut T,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
Expand All @@ -22,7 +21,6 @@ impl<T> Default for HandleWithDtor<T> {
}
pub type HandleValue = HandleWithDtor<::std::os::raw::c_int>;
#[repr(C)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct WithoutDtor {
pub shouldBeWithDtor: HandleValue,
}
Expand Down
20 changes: 18 additions & 2 deletions tests/expectations/tests/crtp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ fn bindgen_test_layout_Derived() {
);
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct BaseWithDestructor {
pub _address: u8,
}
impl Default for BaseWithDestructor {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[repr(C)]
#[derive(Debug, Default)]
pub struct DerivedFromBaseWithDestructor {
pub _address: u8,
}
Expand All @@ -51,6 +58,15 @@ fn bindgen_test_layout_DerivedFromBaseWithDestructor() {
concat!("Alignment of ", stringify!(DerivedFromBaseWithDestructor))
);
}
impl Default for DerivedFromBaseWithDestructor {
fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
unsafe {
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
s.assume_init()
}
}
}
#[test]
fn __bindgen_test_layout_Base_open0_Derived_close0_instantiation() {
assert_eq!(
Expand Down

0 comments on commit c8bc986

Please sign in to comment.