Skip to content

Commit 5ba9bd2

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 5ba9bd2

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

src/codegen/mod.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,9 @@ bitflags! {
110110
}
111111
}
112112

113-
fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
113+
fn derives_of_item(item: &Item, ctx: &BindgenContext, packed: Option<bool>) -> 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,6 +129,20 @@ fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
137129
// It's not hard to fix though.
138130
derivable_traits |= DerivableTraits::CLONE;
139131
}
132+
} else if let Some(packed) = packed {
133+
// If the struct or union is packed, deriving from Copy is required for
134+
// deriving from any other trait.
135+
if packed {
136+
return derivable_traits;
137+
}
138+
}
139+
140+
if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
141+
derivable_traits |= DerivableTraits::DEBUG;
142+
}
143+
144+
if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
145+
derivable_traits |= DerivableTraits::DEFAULT;
140146
}
141147

142148
if item.can_derive_hash(ctx) {
@@ -926,7 +932,7 @@ impl CodeGenerator for Type {
926932

927933
let mut attributes =
928934
vec![attributes::repr("transparent")];
929-
let derivable_traits = derives_of_item(item, ctx);
935+
let derivable_traits = derives_of_item(item, ctx, None);
930936
if !derivable_traits.is_empty() {
931937
let derives: Vec<_> = derivable_traits.into();
932938
attributes.push(attributes::derives(&derives))
@@ -2026,7 +2032,7 @@ impl CodeGenerator for CompInfo {
20262032
}
20272033
}
20282034

2029-
let derivable_traits = derives_of_item(item, ctx);
2035+
let derivable_traits = derives_of_item(item, ctx, Some(packed));
20302036
if !derivable_traits.contains(DerivableTraits::DEBUG) {
20312037
needs_debug_impl = ctx.options().derive_debug &&
20322038
ctx.options().impl_debug &&
@@ -3048,7 +3054,7 @@ impl CodeGenerator for Enum {
30483054
}
30493055

30503056
if !variation.is_const() {
3051-
let mut derives = derives_of_item(item, ctx);
3057+
let mut derives = derives_of_item(item, ctx, None);
30523058
// For backwards compat, enums always derive
30533059
// Clone/Eq/PartialEq/Hash, even if we don't generate those by
30543060
// default.

tests/expectations/tests/packed-vtable.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#[repr(C)]
1010
pub struct PackedVtable__bindgen_vtable(::std::os::raw::c_void);
1111
#[repr(C, packed)]
12-
#[derive(Debug)]
1312
pub struct PackedVtable {
1413
pub vtable_: *const PackedVtable__bindgen_vtable,
1514
}

0 commit comments

Comments
 (0)