summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Seppanen <eds@reric.net>2021-11-07 13:41:19 -0800
committerEmilio Cobos Álvarez <emilio@crisal.io>2021-11-26 02:33:39 +0100
commit0a24ab3a304e7d8f0a08918413145667cabb9aaa (patch)
tree2c8e1cc91f51c4f87e8cb5ea621049e67e00357a
parent2aed6b0216805e27228ed39988ffe1a1ffd7e940 (diff)
allow custom derives on enums
Custom derives are just as useful on enums as they are on structs; not supporting this was an oversight. Adds a test that will fail to compile if the custom derive doesn't work on enums. This test fails without the codegen fix.
-rw-r--r--bindgen-integration/build.rs4
-rw-r--r--bindgen-integration/cpp/Test.h7
-rwxr-xr-xbindgen-integration/src/lib.rs10
-rw-r--r--src/codegen/mod.rs10
4 files changed, 31 insertions, 0 deletions
diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs
index fa0246c4..77ea64b5 100644
--- a/bindgen-integration/build.rs
+++ b/bindgen-integration/build.rs
@@ -126,6 +126,10 @@ impl ParseCallbacks for MacroCallback {
vec![
"PartialEq".into(),
]
+ } else if name == "MyOrderedEnum" {
+ vec![
+ "PartialOrd".into(),
+ ]
} else {
vec![]
}
diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h
index ad71b0f6..eee1974c 100644
--- a/bindgen-integration/cpp/Test.h
+++ b/bindgen-integration/cpp/Test.h
@@ -234,3 +234,10 @@ typedef union {
} Coord;
Coord coord(double x, double y, double z, double t);
+
+// Used to test custom derives on enum. See `test_custom_derive`.
+enum MyOrderedEnum {
+ MICRON,
+ METER,
+ LIGHTYEAR,
+};
diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs
index f56e7259..43f71580 100755
--- a/bindgen-integration/src/lib.rs
+++ b/bindgen-integration/src/lib.rs
@@ -275,4 +275,14 @@ fn test_custom_derive() {
let test1 = unsafe { bindings::Test::new(5) };
let test2 = unsafe { bindings::Test::new(6) };
assert_ne!(test1, test2);
+
+ // The `add_derives` callback should have added `#[derive(PartialOrd)]`
+ // to the `MyOrderedEnum` enum. If it didn't, this will fail to compile.
+
+ let micron = unsafe { bindings::MyOrderedEnum::MICRON };
+ let meter = unsafe { bindings::MyOrderedEnum::METER };
+ let lightyear = unsafe { bindings::MyOrderedEnum::LIGHTYEAR };
+
+ assert!(meter < lightyear);
+ assert!(meter > micron);
}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 69dde2c5..b703a106 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -3014,6 +3014,16 @@ impl CodeGenerator for Enum {
derives.push(derive);
}
}
+
+ // The custom derives callback may return a list of derive attributes;
+ // add them to the end of the list.
+ let custom_derives;
+ if let Some(cb) = &ctx.options().parse_callbacks {
+ custom_derives = cb.add_derives(&name);
+ // In most cases this will be a no-op, since custom_derives will be empty.
+ derives.extend(custom_derives.iter().map(|s| s.as_str()));
+ };
+
attrs.push(attributes::derives(&derives));
}