Skip to content

Commit 416674c

Browse files
committed
Add #[derive(Debug)] to all structs and enums.
Don't derive debug on a struct if one of it's members isn't Debug. Add a new test for this case. Fixes rust-lang#261
1 parent fa6f440 commit 416674c

File tree

6 files changed

+127
-1
lines changed

6 files changed

+127
-1
lines changed

src/gen.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String,
505505
let mut unnamed: u32 = 0;
506506
let mut bitfields: u32 = 0;
507507

508+
// Debug is only defined on little arrays
509+
let mut can_derive_debug = true;
510+
508511
for m in &members {
509512
let (opt_rc_c, opt_f) = match *m {
510513
CompMember::Field(ref f) => { (None, Some(f)) }
@@ -521,6 +524,10 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String,
521524
None => rust_type_id(ctx, f.name.clone())
522525
};
523526

527+
if !f.ty.can_derive_debug() {
528+
can_derive_debug = false;
529+
}
530+
524531
let f_ty = P(cty_to_rs(ctx, &f.ty));
525532

526533
fields.push(respan(ctx.span, ast::StructField_ {
@@ -554,8 +561,12 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: String,
554561
);
555562

556563
let id = rust_type_id(ctx, name.clone());
564+
let mut attrs = vec!(mk_repr_attr(ctx, layout), mk_deriving_copy_attr(ctx, false));
565+
if can_derive_debug {
566+
attrs.push(mk_deriving_debug_attr(ctx));
567+
}
557568
let struct_def = P(ast::Item { ident: ctx.ext_cx.ident_of(&id[..]),
558-
attrs: vec!(mk_repr_attr(ctx, layout), mk_deriving_copy_attr(ctx, false)),
569+
attrs: attrs,
559570
id: ast::DUMMY_NODE_ID,
560571
node: def,
561572
vis: ast::Visibility::Public,
@@ -947,6 +958,19 @@ fn mk_deriving_copy_attr(ctx: &mut GenCtx, clone: bool) -> ast::Attribute {
947958
})
948959
}
949960

961+
fn mk_deriving_debug_attr(ctx: &mut GenCtx) -> ast::Attribute {
962+
let words = vec!(ctx.ext_cx.meta_word(ctx.span, InternedString::new("Debug")));
963+
964+
let attr_val = ctx.ext_cx.meta_list(ctx.span, InternedString::new("derive"), words);
965+
966+
respan(ctx.span, ast::Attribute_ {
967+
id: mk_attr_id(),
968+
style: ast::AttrStyle::Outer,
969+
value: attr_val,
970+
is_sugared_doc: false
971+
})
972+
}
973+
950974
fn cvar_to_rs(ctx: &mut GenCtx, name: String,
951975
ty: &Type,
952976
is_const: bool) -> ast::ForeignItem {

src/types.rs

+17
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,23 @@ impl Type {
123123
TFuncPtr(..) => 0,
124124
}
125125
}
126+
127+
pub fn can_derive_debug(&self) -> bool {
128+
match self {
129+
&TArray(_, size, _) => size <= 32,
130+
&TComp(ref comp) => {
131+
comp.borrow()
132+
.members
133+
.iter()
134+
.all(|member| match member {
135+
&CompMember::Field(ref f) |
136+
&CompMember::CompField(_, ref f) => f.ty.can_derive_debug(),
137+
_ => true,
138+
})
139+
}
140+
_ => true,
141+
}
142+
}
126143
}
127144

128145
#[derive(Copy, Clone, PartialEq)]
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct LittleArray {
2+
int a[32];
3+
};
4+
5+
struct BigArray{
6+
int a[33];
7+
};
8+
9+
struct WithLittleArray {
10+
struct LittleArray a;
11+
};
12+
13+
struct WithBigArray {
14+
struct BigArray a;
15+
};

tests/test_func.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ fn func_ptr_in_struct() {
1616
assert_bind_eq("headers/func_ptr_in_struct.h", "
1717
#[repr(C)]
1818
#[derive(Copy)]
19+
#[derive(Debug)]
1920
pub struct Struct_Foo {
2021
pub bar: ::std::option::Option<
2122
extern \"C\" fn(x: ::std::os::raw::c_int,

tests/test_struct.rs

+68
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ fn with_anon_struct() {
55
assert_bind_eq("headers/struct_with_anon_struct.h", "
66
#[repr(C)]
77
#[derive(Copy)]
8+
#[derive(Debug)]
89
pub struct Struct_foo {
910
pub bar: Struct_Unnamed1,
1011
}
@@ -16,6 +17,7 @@ fn with_anon_struct() {
1617
}
1718
#[repr(C)]
1819
#[derive(Copy)]
20+
#[derive(Debug)]
1921
pub struct Struct_Unnamed1 {
2022
pub a: ::std::os::raw::c_int,
2123
pub b: ::std::os::raw::c_int,
@@ -34,6 +36,7 @@ fn with_anon_struct_array() {
3436
assert_bind_eq("headers/struct_with_anon_struct_array.h", "
3537
#[repr(C)]
3638
#[derive(Copy)]
39+
#[derive(Debug)]
3740
pub struct Struct_foo {
3841
pub bar: [Struct_Unnamed1; 2usize],
3942
pub baz: [[[Struct_Unnamed2; 4usize]; 3usize]; 2usize],
@@ -49,6 +52,7 @@ fn with_anon_struct_array() {
4952
5053
#[repr(C)]
5154
#[derive(Copy)]
55+
#[derive(Debug)]
5256
pub struct Struct_Unnamed1 {
5357
pub a: ::std::os::raw::c_int,
5458
pub b: ::std::os::raw::c_int,
@@ -64,6 +68,7 @@ fn with_anon_struct_array() {
6468
6569
#[repr(C)]
6670
#[derive(Copy)]
71+
#[derive(Debug)]
6772
pub struct Struct_Unnamed2 {
6873
pub a: ::std::os::raw::c_int,
6974
pub b: ::std::os::raw::c_int,
@@ -84,6 +89,7 @@ fn with_anon_struct_pointer() {
8489
assert_bind_eq("headers/struct_with_anon_struct_pointer.h", "
8590
#[repr(C)]
8691
#[derive(Copy)]
92+
#[derive(Debug)]
8793
pub struct Struct_foo {
8894
pub bar: *mut Struct_Unnamed1,
8995
}
@@ -95,6 +101,7 @@ fn with_anon_struct_pointer() {
95101
}
96102
#[repr(C)]
97103
#[derive(Copy)]
104+
#[derive(Debug)]
98105
pub struct Struct_Unnamed1 {
99106
pub a: ::std::os::raw::c_int,
100107
pub b: ::std::os::raw::c_int,
@@ -113,6 +120,7 @@ fn with_anon_union() {
113120
assert_bind_eq("headers/struct_with_anon_union.h", "
114121
#[repr(C)]
115122
#[derive(Copy)]
123+
#[derive(Debug)]
116124
pub struct Struct_foo {
117125
pub bar: Union_Unnamed1,
118126
}
@@ -151,6 +159,7 @@ fn with_anon_unnamed_struct() {
151159
assert_bind_eq("headers/struct_with_anon_unnamed_struct.h", "
152160
#[repr(C)]
153161
#[derive(Copy)]
162+
#[derive(Debug)]
154163
pub struct Struct_foo {
155164
pub _bindgen_data_1_: [u32; 2usize],
156165
}
@@ -178,6 +187,7 @@ fn with_anon_unnamed_union() {
178187
assert_bind_eq("headers/struct_with_anon_unnamed_union.h", "
179188
#[repr(C)]
180189
#[derive(Copy)]
190+
#[derive(Debug)]
181191
pub struct Struct_foo {
182192
pub _bindgen_data_1_: [u32; 1usize],
183193
}
@@ -205,6 +215,7 @@ fn with_nesting() {
205215
assert_bind_eq("headers/struct_with_nesting.h", "
206216
#[repr(C)]
207217
#[derive(Copy)]
218+
#[derive(Debug)]
208219
pub struct Struct_foo {
209220
pub a: ::std::os::raw::c_uint,
210221
pub _bindgen_data_1_: [u32; 1usize],
@@ -253,6 +264,7 @@ fn containing_fwd_decl_struct() {
253264
assert_bind_eq("headers/struct_containing_forward_declared_struct.h", "
254265
#[repr(C)]
255266
#[derive(Copy)]
267+
#[derive(Debug)]
256268
pub struct Struct_a {
257269
pub val_a: *mut Struct_b,
258270
}
@@ -267,6 +279,7 @@ fn containing_fwd_decl_struct() {
267279
268280
#[repr(C)]
269281
#[derive(Copy)]
282+
#[derive(Debug)]
270283
pub struct Struct_b {
271284
pub val_b: ::std::os::raw::c_int,
272285
}
@@ -286,6 +299,7 @@ fn with_bitfields() {
286299
assert_bind_eq("headers/struct_with_bitfields.h", "
287300
#[repr(C)]
288301
#[derive(Copy)]
302+
#[derive(Debug)]
289303
pub struct Struct_bitfield {
290304
pub _bindgen_bitfield_1_: ::std::os::raw::c_ushort,
291305
pub e: ::std::os::raw::c_int,
@@ -308,6 +322,7 @@ fn with_fwd_decl_struct() {
308322
assert_bind_eq("headers/forward_declared_struct.h", "
309323
#[repr(C)]
310324
#[derive(Copy)]
325+
#[derive(Debug)]
311326
pub struct Struct_a {
312327
pub b: ::std::os::raw::c_int,
313328
}
@@ -319,6 +334,7 @@ fn with_fwd_decl_struct() {
319334
}
320335
#[repr(C)]
321336
#[derive(Copy)]
337+
#[derive(Debug)]
322338
pub struct Struct_c {
323339
pub d: ::std::os::raw::c_int,
324340
}
@@ -337,6 +353,7 @@ fn packed_struct() {
337353
assert_bind_eq("headers/struct_with_packing.h", "
338354
#[repr(C, packed)]
339355
#[derive(Copy)]
356+
#[derive(Debug)]
340357
pub struct Struct_a {
341358
pub b: ::std::os::raw::c_char,
342359
pub c: ::std::os::raw::c_short,
@@ -350,3 +367,54 @@ fn packed_struct() {
350367
");
351368
}
352369

370+
#[test]
371+
fn derive_debug_big_array() {
372+
assert_bind_eq("headers/struct_with_derive_debug.h", "
373+
#[repr(C)]
374+
#[derive(Copy)]
375+
#[derive(Debug)]
376+
pub struct Struct_LittleArray {
377+
pub a: [::std::os::raw::c_int; 32usize],
378+
}
379+
impl ::std::clone::Clone for Struct_LittleArray {
380+
fn clone(&self) -> Self { *self }
381+
}
382+
impl ::std::default::Default for Struct_LittleArray {
383+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
384+
}
385+
#[repr(C)]
386+
#[derive(Copy)]
387+
pub struct Struct_BigArray {
388+
pub a: [::std::os::raw::c_int; 33usize],
389+
}
390+
impl ::std::clone::Clone for Struct_BigArray {
391+
fn clone(&self) -> Self { *self }
392+
}
393+
impl ::std::default::Default for Struct_BigArray {
394+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
395+
}
396+
#[repr(C)]
397+
#[derive(Copy)]
398+
#[derive(Debug)]
399+
pub struct Struct_WithLittleArray {
400+
pub a: Struct_LittleArray,
401+
}
402+
impl ::std::clone::Clone for Struct_WithLittleArray {
403+
fn clone(&self) -> Self { *self }
404+
}
405+
impl ::std::default::Default for Struct_WithLittleArray {
406+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
407+
}
408+
#[repr(C)]
409+
#[derive(Copy)]
410+
pub struct Struct_WithBigArray {
411+
pub a: Struct_BigArray,
412+
}
413+
impl ::std::clone::Clone for Struct_WithBigArray {
414+
fn clone(&self) -> Self { *self }
415+
}
416+
impl ::std::default::Default for Struct_WithBigArray {
417+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
418+
}
419+
");
420+
}

tests/test_union.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fn with_anon_struct() {
2222
}
2323
#[repr(C)]
2424
#[derive(Copy)]
25+
#[derive(Debug)]
2526
pub struct Struct_Unnamed1 {
2627
pub a: ::std::os::raw::c_uint,
2728
pub b: ::std::os::raw::c_uint,

0 commit comments

Comments
 (0)