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,
 }