Skip to content

Commit 3a7ba55

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: #2083 Signed-off-by: Michal Rostecki <[email protected]>
1 parent ee6ff69 commit 3a7ba55

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

src/codegen/mod.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,13 @@ bitflags! {
110110
}
111111
}
112112

113-
fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
113+
fn derives_of_item(
114+
item: &Item,
115+
ctx: &BindgenContext,
116+
packed: bool,
117+
) -> DerivableTraits {
114118
let mut derivable_traits = DerivableTraits::empty();
115119

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-
124120
let all_template_params = item.all_template_params(ctx);
125121

126122
if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
@@ -137,6 +133,18 @@ fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
137133
// It's not hard to fix though.
138134
derivable_traits |= DerivableTraits::CLONE;
139135
}
136+
} else if packed {
137+
// If the struct or union is packed, deriving from Copy is required for
138+
// deriving from any other trait.
139+
return derivable_traits;
140+
}
141+
142+
if item.can_derive_debug(ctx) && !item.annotations().disallow_debug() {
143+
derivable_traits |= DerivableTraits::DEBUG;
144+
}
145+
146+
if item.can_derive_default(ctx) && !item.annotations().disallow_default() {
147+
derivable_traits |= DerivableTraits::DEFAULT;
140148
}
141149

142150
if item.can_derive_hash(ctx) {
@@ -926,7 +934,8 @@ impl CodeGenerator for Type {
926934

927935
let mut attributes =
928936
vec![attributes::repr("transparent")];
929-
let derivable_traits = derives_of_item(item, ctx);
937+
let packed = false; // Types can't be packed in Rust.
938+
let derivable_traits = derives_of_item(item, ctx, packed);
930939
if !derivable_traits.is_empty() {
931940
let derives: Vec<_> = derivable_traits.into();
932941
attributes.push(attributes::derives(&derives))
@@ -2026,7 +2035,7 @@ impl CodeGenerator for CompInfo {
20262035
}
20272036
}
20282037

2029-
let derivable_traits = derives_of_item(item, ctx);
2038+
let derivable_traits = derives_of_item(item, ctx, packed);
20302039
if !derivable_traits.contains(DerivableTraits::DEBUG) {
20312040
needs_debug_impl = ctx.options().derive_debug &&
20322041
ctx.options().impl_debug &&
@@ -3048,7 +3057,8 @@ impl CodeGenerator for Enum {
30483057
}
30493058

30503059
if !variation.is_const() {
3051-
let mut derives = derives_of_item(item, ctx);
3060+
let packed = false; // Enums can't be packed in Rust.
3061+
let mut derives = derives_of_item(item, ctx, packed);
30523062
// For backwards compat, enums always derive
30533063
// Clone/Eq/PartialEq/Hash, even if we don't generate those by
30543064
// default.

tests/expectations/tests/packed-vtable.rs

Lines changed: 0 additions & 1 deletion
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)