Skip to content

Commit

Permalink
Derive from any other trait only when deriving from Copy
Browse files Browse the repository at this point in the history
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 <vadorovsky@gmail.com>
  • Loading branch information
vadorovsky committed May 4, 2022
1 parent ee6ff69 commit dea052e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
34 changes: 22 additions & 12 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,13 @@ bitflags! {
}
}

fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
fn derives_of_item(
item: &Item,
ctx: &BindgenContext,
packed: Option<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() {
Expand All @@ -137,6 +133,20 @@ fn derives_of_item(item: &Item, ctx: &BindgenContext) -> DerivableTraits {
// It's not hard to fix though.
derivable_traits |= DerivableTraits::CLONE;
}
} else if let Some(packed) = packed {
// If the struct or union is packed, deriving from Copy is required for
// deriving from any other trait.
if packed {
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) {
Expand Down Expand Up @@ -926,7 +936,7 @@ impl CodeGenerator for Type {

let mut attributes =
vec![attributes::repr("transparent")];
let derivable_traits = derives_of_item(item, ctx);
let derivable_traits = derives_of_item(item, ctx, None);
if !derivable_traits.is_empty() {
let derives: Vec<_> = derivable_traits.into();
attributes.push(attributes::derives(&derives))
Expand Down Expand Up @@ -2026,7 +2036,7 @@ impl CodeGenerator for CompInfo {
}
}

let derivable_traits = derives_of_item(item, ctx);
let derivable_traits = derives_of_item(item, ctx, Some(packed));
if !derivable_traits.contains(DerivableTraits::DEBUG) {
needs_debug_impl = ctx.options().derive_debug &&
ctx.options().impl_debug &&
Expand Down Expand Up @@ -3048,7 +3058,7 @@ impl CodeGenerator for Enum {
}

if !variation.is_const() {
let mut derives = derives_of_item(item, ctx);
let mut derives = derives_of_item(item, ctx, None);
// For backwards compat, enums always derive
// Clone/Eq/PartialEq/Hash, even if we don't generate those by
// default.
Expand Down
1 change: 0 additions & 1 deletion tests/expectations/tests/packed-vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down

0 comments on commit dea052e

Please sign in to comment.