Skip to content

Commit 6501409

Browse files
committed
Derive from any other trait only when deriving from Copy
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 <[email protected]>
1 parent ee6ff69 commit 6501409

34 files changed

+419
-100
lines changed

src/codegen/mod.rs

+23-24
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,6 @@ bitflags! {
113113
fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
114114
let mut derivable_traits = DerivableTraits::empty();
115115

116-
if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
117-
derivable_traits |= DerivableTraits::DEBUG;
118-
}
119-
120-
if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
121-
derivable_traits |= DerivableTraits::DEFAULT;
122-
}
123-
124116
let all_template_params = item.all_template_params(ctx);
125117

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

142-
if item.can_derive_hash(ctx) {
143-
derivable_traits |= DerivableTraits::HASH;
144-
}
133+
if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
134+
derivable_traits |= DerivableTraits::DEBUG;
135+
}
145136

146-
if item.can_derive_partialord(ctx) {
147-
derivable_traits |= DerivableTraits::PARTIAL_ORD;
148-
}
137+
if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
138+
derivable_traits |= DerivableTraits::DEFAULT;
139+
}
149140

150-
if item.can_derive_ord(ctx) {
151-
derivable_traits |= DerivableTraits::ORD;
152-
}
141+
if item.can_derive_hash(ctx) {
142+
derivable_traits |= DerivableTraits::HASH;
143+
}
153144

154-
if item.can_derive_partialeq(ctx) {
155-
derivable_traits |= DerivableTraits::PARTIAL_EQ;
156-
}
145+
if item.can_derive_partialord(ctx) {
146+
derivable_traits |= DerivableTraits::PARTIAL_ORD;
147+
}
157148

158-
if item.can_derive_eq(ctx) {
159-
derivable_traits |= DerivableTraits::EQ;
149+
if item.can_derive_ord(ctx) {
150+
derivable_traits |= DerivableTraits::ORD;
151+
}
152+
153+
if item.can_derive_partialeq(ctx) {
154+
derivable_traits |= DerivableTraits::PARTIAL_EQ;
155+
}
156+
157+
if item.can_derive_eq(ctx) {
158+
derivable_traits |= DerivableTraits::EQ;
159+
}
160160
}
161161

162162
derivable_traits
@@ -4554,7 +4554,6 @@ pub mod utils {
45544554

45554555
let incomplete_array_decl = quote! {
45564556
#[repr(C)]
4557-
#[derive(Default)]
45584557
pub struct __IncompleteArrayField<T>(
45594558
::#prefix::marker::PhantomData<T>, [T; 0]);
45604559
};

tests/expectations/tests/allowlisted_item_references_no_copy.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug, Default)]
109
pub struct NoCopy {
1110
pub _address: u8,
1211
}
@@ -23,8 +22,16 @@ fn bindgen_test_layout_NoCopy() {
2322
concat!("Alignment of ", stringify!(NoCopy))
2423
);
2524
}
25+
impl Default for NoCopy {
26+
fn default() -> Self {
27+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
28+
unsafe {
29+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
30+
s.assume_init()
31+
}
32+
}
33+
}
2634
#[repr(C)]
27-
#[derive(Debug, Default)]
2835
pub struct AllowlistMe {
2936
pub a: NoCopy,
3037
}
@@ -53,3 +60,12 @@ fn bindgen_test_layout_AllowlistMe() {
5360
)
5461
);
5562
}
63+
impl Default for AllowlistMe {
64+
fn default() -> Self {
65+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
66+
unsafe {
67+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
68+
s.assume_init()
69+
}
70+
}
71+
}

tests/expectations/tests/class_with_dtor.rs

-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug, Hash, PartialEq, Eq)]
109
pub struct HandleWithDtor<T> {
1110
pub ptr: *mut T,
1211
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
@@ -22,7 +21,6 @@ impl<T> Default for HandleWithDtor<T> {
2221
}
2322
pub type HandleValue = HandleWithDtor<::std::os::raw::c_int>;
2423
#[repr(C)]
25-
#[derive(Debug, Hash, PartialEq, Eq)]
2624
pub struct WithoutDtor {
2725
pub shouldBeWithDtor: HandleValue,
2826
}

tests/expectations/tests/crtp.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,19 @@ fn bindgen_test_layout_Derived() {
2929
);
3030
}
3131
#[repr(C)]
32-
#[derive(Debug, Default)]
3332
pub struct BaseWithDestructor {
3433
pub _address: u8,
3534
}
35+
impl Default for BaseWithDestructor {
36+
fn default() -> Self {
37+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
38+
unsafe {
39+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
40+
s.assume_init()
41+
}
42+
}
43+
}
3644
#[repr(C)]
37-
#[derive(Debug, Default)]
3845
pub struct DerivedFromBaseWithDestructor {
3946
pub _address: u8,
4047
}
@@ -51,6 +58,15 @@ fn bindgen_test_layout_DerivedFromBaseWithDestructor() {
5158
concat!("Alignment of ", stringify!(DerivedFromBaseWithDestructor))
5259
);
5360
}
61+
impl Default for DerivedFromBaseWithDestructor {
62+
fn default() -> Self {
63+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
64+
unsafe {
65+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
66+
s.assume_init()
67+
}
68+
}
69+
}
5470
#[test]
5571
fn __bindgen_test_layout_Base_open0_Derived_close0_instantiation() {
5672
assert_eq!(

tests/expectations/tests/derive-custom.rs

+102-4
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,119 @@
66
)]
77

88
/// <div rustbindgen derive="Debug"></div>
9+
/// <div rustbindgen derive="Copy"></div>
910
#[repr(C)]
10-
#[derive(Default, Debug)]
11+
#[derive(Debug, Copy)]
1112
pub struct my_type {
1213
pub a: ::std::os::raw::c_int,
1314
}
15+
#[test]
16+
fn bindgen_test_layout_my_type() {
17+
assert_eq!(
18+
::std::mem::size_of::<my_type>(),
19+
4usize,
20+
concat!("Size of: ", stringify!(my_type))
21+
);
22+
assert_eq!(
23+
::std::mem::align_of::<my_type>(),
24+
4usize,
25+
concat!("Alignment of ", stringify!(my_type))
26+
);
27+
assert_eq!(
28+
unsafe { &(*(::std::ptr::null::<my_type>())).a as *const _ as usize },
29+
0usize,
30+
concat!(
31+
"Offset of field: ",
32+
stringify!(my_type),
33+
"::",
34+
stringify!(a)
35+
)
36+
);
37+
}
38+
impl Default for my_type {
39+
fn default() -> Self {
40+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
41+
unsafe {
42+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
43+
s.assume_init()
44+
}
45+
}
46+
}
1447
/// <div rustbindgen derive="Debug"></div>
48+
/// <div rustbindgen derive="Copy"></div>
1549
/// <div rustbindgen derive="Clone"></div>
1650
#[repr(C)]
17-
#[derive(Default, Debug, Clone)]
51+
#[derive(Debug, Copy, Clone)]
1852
pub struct my_type2 {
1953
pub a: ::std::os::raw::c_uint,
2054
}
21-
/// <div rustbindgen derive="Debug" derive="Clone"></div>
55+
#[test]
56+
fn bindgen_test_layout_my_type2() {
57+
assert_eq!(
58+
::std::mem::size_of::<my_type2>(),
59+
4usize,
60+
concat!("Size of: ", stringify!(my_type2))
61+
);
62+
assert_eq!(
63+
::std::mem::align_of::<my_type2>(),
64+
4usize,
65+
concat!("Alignment of ", stringify!(my_type2))
66+
);
67+
assert_eq!(
68+
unsafe { &(*(::std::ptr::null::<my_type2>())).a as *const _ as usize },
69+
0usize,
70+
concat!(
71+
"Offset of field: ",
72+
stringify!(my_type2),
73+
"::",
74+
stringify!(a)
75+
)
76+
);
77+
}
78+
impl Default for my_type2 {
79+
fn default() -> Self {
80+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
81+
unsafe {
82+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
83+
s.assume_init()
84+
}
85+
}
86+
}
87+
/// <div rustbindgen derive="Debug" derive="Copy" derive="Clone"></div>
2288
#[repr(C)]
23-
#[derive(Default, Debug, Clone)]
89+
#[derive(Debug, Copy, Clone)]
2490
pub struct my_type3 {
2591
pub a: ::std::os::raw::c_ulong,
2692
}
93+
#[test]
94+
fn bindgen_test_layout_my_type3() {
95+
assert_eq!(
96+
::std::mem::size_of::<my_type3>(),
97+
8usize,
98+
concat!("Size of: ", stringify!(my_type3))
99+
);
100+
assert_eq!(
101+
::std::mem::align_of::<my_type3>(),
102+
8usize,
103+
concat!("Alignment of ", stringify!(my_type3))
104+
);
105+
assert_eq!(
106+
unsafe { &(*(::std::ptr::null::<my_type3>())).a as *const _ as usize },
107+
0usize,
108+
concat!(
109+
"Offset of field: ",
110+
stringify!(my_type3),
111+
"::",
112+
stringify!(a)
113+
)
114+
);
115+
}
116+
impl Default for my_type3 {
117+
fn default() -> Self {
118+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
119+
unsafe {
120+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
121+
s.assume_init()
122+
}
123+
}
124+
}

tests/expectations/tests/do-not-derive-copy.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug, Default)]
109
pub struct WouldBeCopyButWeAreNotDerivingCopy {
1110
pub x: ::std::os::raw::c_int,
1211
}
@@ -39,3 +38,12 @@ fn bindgen_test_layout_WouldBeCopyButWeAreNotDerivingCopy() {
3938
)
4039
);
4140
}
41+
impl Default for WouldBeCopyButWeAreNotDerivingCopy {
42+
fn default() -> Self {
43+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
44+
unsafe {
45+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
46+
s.assume_init()
47+
}
48+
}
49+
}

tests/expectations/tests/gen-destructors-neg.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug, Default)]
109
pub struct Foo {
1110
pub bar: ::std::os::raw::c_int,
1211
}
@@ -28,3 +27,12 @@ fn bindgen_test_layout_Foo() {
2827
concat!("Offset of field: ", stringify!(Foo), "::", stringify!(bar))
2928
);
3029
}
30+
impl Default for Foo {
31+
fn default() -> Self {
32+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
33+
unsafe {
34+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
35+
s.assume_init()
36+
}
37+
}
38+
}

tests/expectations/tests/gen-destructors.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug, Default)]
109
pub struct Foo {
1110
pub bar: ::std::os::raw::c_int,
1211
}
@@ -32,6 +31,15 @@ extern "C" {
3231
#[link_name = "\u{1}_ZN3FooD1Ev"]
3332
pub fn Foo_Foo_destructor(this: *mut Foo);
3433
}
34+
impl Default for Foo {
35+
fn default() -> Self {
36+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
37+
unsafe {
38+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
39+
s.assume_init()
40+
}
41+
}
42+
}
3543
impl Foo {
3644
#[inline]
3745
pub unsafe fn destruct(&mut self) {

tests/expectations/tests/inline_namespace_no_ns_enabled.rs

-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug)]
109
pub struct std_basic_string<CharT> {
1110
pub hider: std_basic_string_Alloc_hider,
1211
pub length: ::std::os::raw::c_ulong,
@@ -28,7 +27,6 @@ impl Default for std_basic_string_Alloc_hider {
2827
}
2928
}
3029
#[repr(C)]
31-
#[derive(Debug)]
3230
pub struct std_basic_string__bindgen_ty_1<CharT> {
3331
pub inline_storage: [CharT; 4usize],
3432
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<CharT>>,

tests/expectations/tests/issue-1197-pure-virtual-stuff.rs

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#[repr(C)]
99
pub struct Foo__bindgen_vtable(::std::os::raw::c_void);
1010
#[repr(C)]
11-
#[derive(Debug)]
1211
pub struct Foo {
1312
pub vtable_: *const Foo__bindgen_vtable,
1413
}

tests/expectations/tests/issue-1238-fwd-no-copy.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
)]
77

88
#[repr(C)]
9-
#[derive(Debug)]
109
pub struct MyType {
1110
_unused: [u8; 0],
1211
}

tests/expectations/tests/issue-1454.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
pub struct extern_type;
1111

1212
#[repr(C)]
13-
#[derive(Debug)]
1413
pub struct local_type {
1514
pub inner: extern_type,
1615
}

0 commit comments

Comments
 (0)