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 <vadorovsky@gmail.com>
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 99cdf3c..4fcbaef 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -110,17 +110,13 @@
}
}
-fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
+fn derives_of_item(
+ item: &Item,
+ ctx: &BindgenContext,
+ packed: bool,
+) -> 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() {
@@ -137,6 +133,18 @@
// It's not hard to fix though.
derivable_traits |= DerivableTraits::CLONE;
}
+ } else if packed {
+ // If the struct or union is packed, deriving from Copy is required for
+ // deriving from any other trait.
+ return derivable_traits;
+ }
+
+ 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;
}
if item.can_derive_hash(ctx) {
@@ -926,7 +934,9 @@
let mut attributes =
vec![attributes::repr("transparent")];
- let derivable_traits = derives_of_item(item, ctx);
+ let packed = false; // Types can't be packed in Rust.
+ let derivable_traits =
+ derives_of_item(item, ctx, packed);
if !derivable_traits.is_empty() {
let derives: Vec<_> = derivable_traits.into();
attributes.push(attributes::derives(&derives))
@@ -2026,7 +2036,7 @@
}
}
- let derivable_traits = derives_of_item(item, ctx);
+ let derivable_traits = derives_of_item(item, ctx, packed);
if !derivable_traits.contains(DerivableTraits::DEBUG) {
needs_debug_impl = ctx.options().derive_debug &&
ctx.options().impl_debug &&
@@ -3048,7 +3058,8 @@
}
if !variation.is_const() {
- let mut derives = derives_of_item(item, ctx);
+ let packed = false; // Enums can't be packed in Rust.
+ let mut derives = derives_of_item(item, ctx, packed);
// For backwards compat, enums always derive
// Clone/Eq/PartialEq/Hash, even if we don't generate those by
// default.
diff --git a/tests/expectations/tests/packed-vtable.rs b/tests/expectations/tests/packed-vtable.rs
index 0069ead..7168815 100644
--- a/tests/expectations/tests/packed-vtable.rs
+++ b/tests/expectations/tests/packed-vtable.rs
@@ -9,7 +9,6 @@
#[repr(C)]
pub struct PackedVtable__bindgen_vtable(::std::os::raw::c_void);
#[repr(C, packed)]
-#[derive(Debug)]
pub struct PackedVtable {
pub vtable_: *const PackedVtable__bindgen_vtable,
}