Skip to content

Commit

Permalink
Allow custom derives on new-type alias
Browse files Browse the repository at this point in the history
  • Loading branch information
arctic-alpaca authored and emilio committed Mar 19, 2024
1 parent f158981 commit 67115d9
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
3 changes: 3 additions & 0 deletions bindgen-integration/build.rs
Expand Up @@ -128,6 +128,8 @@ impl ParseCallbacks for MacroCallback {
vec!["PartialEq".into()]
} else if info.name == "MyOrderedEnum" {
vec!["std::cmp::PartialOrd".into()]
} else if info.name == "TestDeriveOnAlias" {
vec!["std::cmp::PartialEq".into(), "std::cmp::PartialOrd".into()]
} else {
vec![]
}
Expand Down Expand Up @@ -193,6 +195,7 @@ fn setup_macro_test() {
.blocklist_function("my_prefixed_function_to_remove")
.constified_enum("my_prefixed_enum_to_be_constified")
.opaque_type("my_prefixed_templated_foo<my_prefixed_baz>")
.new_type_alias("TestDeriveOnAlias")
.depfile(out_rust_file_relative.display().to_string(), &out_dep_file)
.generate()
.expect("Unable to generate bindings");
Expand Down
3 changes: 3 additions & 0 deletions bindgen-integration/cpp/Test.h
Expand Up @@ -241,3 +241,6 @@ enum MyOrderedEnum {
METER,
LIGHTYEAR,
};

// Used to test custom derives on new-type alias. See `test_custom_derive`.
typedef int TestDeriveOnAlias;
7 changes: 7 additions & 0 deletions bindgen-integration/src/lib.rs
Expand Up @@ -289,6 +289,13 @@ fn test_custom_derive() {

assert!(meter < lightyear);
assert!(meter > micron);

// The `add_derives` callback should have added `#[derive(PartialEq, PartialOrd)]`
// to the `TestDeriveOnAlias` new-type alias. If it didn't, this will fail to compile.
let test1 = unsafe { bindings::TestDeriveOnAlias(5) };
let test2 = unsafe { bindings::TestDeriveOnAlias(6) };
assert!(test1 < test2);
assert!(!(test1 > test2));
}

#[test]
Expand Down
18 changes: 14 additions & 4 deletions bindgen/codegen/mod.rs
Expand Up @@ -1022,10 +1022,20 @@ impl CodeGenerator for Type {
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))
}
let mut derives: Vec<_> = derivable_traits.into();
// The custom derives callback may return a list of derive attributes;
// add them to the end of the list.
let custom_derives =
ctx.options().all_callbacks(|cb| {
cb.add_derives(&DeriveInfo {
name: &name,
kind: DeriveTypeKind::Struct,
})
});
// 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()));
attributes.push(attributes::derives(&derives));

quote! {
#( #attributes )*
Expand Down

0 comments on commit 67115d9

Please sign in to comment.