Skip to content

Commit e8805de

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 e8805de

File tree

2 files changed

+23
-13
lines changed

2 files changed

+23
-13
lines changed

src/codegen/mod.rs

+23-12
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,9 @@ 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 =
939+
derives_of_item(item, ctx, packed);
930940
if !derivable_traits.is_empty() {
931941
let derives: Vec<_> = derivable_traits.into();
932942
attributes.push(attributes::derives(&derives))
@@ -2026,7 +2036,7 @@ impl CodeGenerator for CompInfo {
20262036
}
20272037
}
20282038

2029-
let derivable_traits = derives_of_item(item, ctx);
2039+
let derivable_traits = derives_of_item(item, ctx, packed);
20302040
if !derivable_traits.contains(DerivableTraits::DEBUG) {
20312041
needs_debug_impl = ctx.options().derive_debug &&
20322042
ctx.options().impl_debug &&
@@ -3048,7 +3058,8 @@ impl CodeGenerator for Enum {
30483058
}
30493059

30503060
if !variation.is_const() {
3051-
let mut derives = derives_of_item(item, ctx);
3061+
let packed = false; // Enums can't be packed in Rust.
3062+
let mut derives = derives_of_item(item, ctx, packed);
30523063
// For backwards compat, enums always derive
30533064
// Clone/Eq/PartialEq/Hash, even if we don't generate those by
30543065
// 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)