Skip to content

Commit 4013431

Browse files
authored
Merge pull request #1453 from flowbish/custom_derive. r=emilio
Add source annotation to express explicit derives for a type.
2 parents adfc52a + 94698e0 commit 4013431

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

src/codegen/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,8 @@ impl CodeGenerator for CompInfo {
17641764
derives.push("Eq");
17651765
}
17661766

1767+
derives.extend(item.annotations().derives().iter().map(String::as_str));
1768+
17671769
if !derives.is_empty() {
17681770
attributes.push(attributes::derives(&derives))
17691771
}

src/ir/annotations.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub struct Annotations {
5858
/// In that case, bindgen will generate a constant for `Bar` instead of
5959
/// `Baz`.
6060
constify_enum_variant: bool,
61+
/// List of explicit derives for this type.
62+
derives: Vec<String>,
6163
}
6264

6365
fn parse_accessor(s: &str) -> FieldAccessorKind {
@@ -79,6 +81,7 @@ impl Default for Annotations {
7981
private_fields: None,
8082
accessor_kind: None,
8183
constify_enum_variant: false,
84+
derives: vec![],
8285
}
8386
}
8487
}
@@ -130,6 +133,11 @@ impl Annotations {
130133
self.use_instead_of.as_ref().map(|s| &**s)
131134
}
132135

136+
/// The list of derives that have been specified in this annotation.
137+
pub fn derives(&self) -> &[String] {
138+
&self.derives
139+
}
140+
133141
/// Should we avoid implementing the `Copy` trait?
134142
pub fn disallow_copy(&self) -> bool {
135143
self.disallow_copy
@@ -165,6 +173,9 @@ impl Annotations {
165173
attr.value.split("::").map(Into::into).collect(),
166174
)
167175
}
176+
"derive" => {
177+
self.derives.push(attr.value)
178+
}
168179
"private" => {
169180
self.private_fields = Some(attr.value != "false")
170181
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
/// <div rustbindgen derive="Debug"></div>
11+
#[repr(C)]
12+
#[derive(Default, Debug)]
13+
pub struct my_type {
14+
pub a: ::std::os::raw::c_int,
15+
}
16+
#[test]
17+
fn bindgen_test_layout_my_type() {
18+
assert_eq!(
19+
::std::mem::size_of::<my_type>(),
20+
4usize,
21+
concat!("Size of: ", stringify!(my_type))
22+
);
23+
assert_eq!(
24+
::std::mem::align_of::<my_type>(),
25+
4usize,
26+
concat!("Alignment of ", stringify!(my_type))
27+
);
28+
assert_eq!(
29+
unsafe { &(*(::std::ptr::null::<my_type>())).a as *const _ as usize },
30+
0usize,
31+
concat!(
32+
"Offset of field: ",
33+
stringify!(my_type),
34+
"::",
35+
stringify!(a)
36+
)
37+
);
38+
}
39+
/// <div rustbindgen derive="Debug"></div>
40+
/// <div rustbindgen derive="Clone"></div>
41+
#[repr(C)]
42+
#[derive(Default, Debug, Clone)]
43+
pub struct my_type2 {
44+
pub a: ::std::os::raw::c_uint,
45+
}
46+
#[test]
47+
fn bindgen_test_layout_my_type2() {
48+
assert_eq!(
49+
::std::mem::size_of::<my_type2>(),
50+
4usize,
51+
concat!("Size of: ", stringify!(my_type2))
52+
);
53+
assert_eq!(
54+
::std::mem::align_of::<my_type2>(),
55+
4usize,
56+
concat!("Alignment of ", stringify!(my_type2))
57+
);
58+
assert_eq!(
59+
unsafe { &(*(::std::ptr::null::<my_type2>())).a as *const _ as usize },
60+
0usize,
61+
concat!(
62+
"Offset of field: ",
63+
stringify!(my_type2),
64+
"::",
65+
stringify!(a)
66+
)
67+
);
68+
}
69+
/// <div rustbindgen derive="Debug" derive="Clone"></div>
70+
#[repr(C)]
71+
#[derive(Default, Debug, Clone)]
72+
pub struct my_type3 {
73+
pub a: ::std::os::raw::c_ulong,
74+
}
75+
#[test]
76+
fn bindgen_test_layout_my_type3() {
77+
assert_eq!(
78+
::std::mem::size_of::<my_type3>(),
79+
8usize,
80+
concat!("Size of: ", stringify!(my_type3))
81+
);
82+
assert_eq!(
83+
::std::mem::align_of::<my_type3>(),
84+
8usize,
85+
concat!("Alignment of ", stringify!(my_type3))
86+
);
87+
assert_eq!(
88+
unsafe { &(*(::std::ptr::null::<my_type3>())).a as *const _ as usize },
89+
0usize,
90+
concat!(
91+
"Offset of field: ",
92+
stringify!(my_type3),
93+
"::",
94+
stringify!(a)
95+
)
96+
);
97+
}

tests/headers/derive-custom.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// bindgen-flags: --no-derive-debug --no-derive-copy --default-enum-style rust
2+
3+
/** <div rustbindgen derive="Debug"></div> */
4+
struct my_type;
5+
6+
/** <div rustbindgen derive="Clone"></div> */
7+
struct my_type;
8+
9+
struct my_type {
10+
int a;
11+
};
12+
13+
/**
14+
* <div rustbindgen derive="Debug"></div>
15+
* <div rustbindgen derive="Clone"></div>
16+
*/
17+
struct my_type2;
18+
19+
struct my_type2 {
20+
unsigned a;
21+
};
22+
23+
/**
24+
* <div rustbindgen derive="Debug" derive="Clone"></div>
25+
*/
26+
struct my_type3 {
27+
unsigned long a;
28+
};

0 commit comments

Comments
 (0)