Skip to content

Commit ca9f853

Browse files
committed
types: Fix can_derive_copy() in edge cases
1 parent 4a8fea5 commit ca9f853

File tree

5 files changed

+62
-5
lines changed

5 files changed

+62
-5
lines changed

src/types.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,36 @@ impl Type {
235235
}
236236
}
237237

238-
fn can_derive_copy(&self) -> bool {
239-
!self.is_opaque() && match *self {
238+
// For some reason, deriving copies of an array of a type that is not known to be copy
239+
// is a compile error. e.g.:
240+
//
241+
// #[derive(Copy)]
242+
// struct A<T> {
243+
// member: T,
244+
// }
245+
//
246+
// is fine, while:
247+
//
248+
// #[derive(Copy)]
249+
// struct A<T> {
250+
// member: [T; 1],
251+
// }
252+
//
253+
// is an error.
254+
//
255+
// That's the point of the existance of can_derive_copy_in_array().
256+
pub fn can_derive_copy_in_array(&self) -> bool {
257+
match *self {
240258
TVoid => false,
241-
TArray(ref t, _, _) => t.can_derive_copy(),
259+
TNamed(ref ti) => ti.borrow().ty.can_derive_copy_in_array(),
260+
TArray(ref t, _, _) => t.can_derive_copy_in_array(),
261+
ref t => t.can_derive_copy(),
262+
}
263+
}
264+
265+
pub fn can_derive_copy(&self) -> bool {
266+
!self.is_opaque() && match *self {
267+
TArray(ref t, _, _) => t.can_derive_copy_in_array(),
242268
TNamed(ref ti) => ti.borrow().ty.can_derive_copy(),
243269
TComp(ref comp) => comp.borrow().can_derive_copy(),
244270
_ => true,

tests/expectations/class_nested.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn bindgen_test_layout_Struct_D() {
4545
assert_eq!(::std::mem::align_of::<Struct_D>() , 4usize);
4646
}
4747
#[repr(C)]
48-
#[derive(Debug)]
48+
#[derive(Debug, Copy, Clone)]
4949
pub struct Struct_Templated<T> {
5050
pub member: T,
5151
}

tests/expectations/template.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ pub struct Struct_D_U<T, Z> {
2727
pub m_baz: Z,
2828
pub _phantom0: ::std::marker::PhantomData<T>,
2929
}
30+
#[repr(C)]
31+
#[derive(Debug, Copy, Clone)]
32+
pub struct Struct_Rooted<T> {
33+
pub prev: *mut T,
34+
pub next: *mut T,
35+
pub ptr: T,
36+
}
37+
#[repr(C)]
38+
#[derive(Debug, Copy)]
39+
pub struct Struct_RootedContainer {
40+
pub root: Struct_Rooted<*mut ::std::os::raw::c_void>,
41+
}
42+
impl ::std::clone::Clone for Struct_RootedContainer {
43+
fn clone(&self) -> Self { *self }
44+
}
45+
#[test]
46+
fn bindgen_test_layout_Struct_RootedContainer() {
47+
assert_eq!(::std::mem::size_of::<Struct_RootedContainer>() , 24usize);
48+
assert_eq!(::std::mem::align_of::<Struct_RootedContainer>() , 8usize);
49+
}
3050
extern "C" {
3151
#[link_name = "_Z3bar3FooIiiE"]
3252
pub fn bar(foo: Struct_Foo<::std::os::raw::c_int, ::std::os::raw::c_int>);

tests/expectations/using.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
#[repr(C)]
9-
#[derive(Debug)]
9+
#[derive(Debug, Copy, Clone)]
1010
pub struct Struct_Point<T> {
1111
pub x: T,
1212
pub y: T,

tests/headers/template.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,14 @@ class D {
1818
Z m_baz;
1919
};
2020
};
21+
22+
template<typename T>
23+
class Rooted {
24+
T* prev;
25+
T* next;
26+
T ptr;
27+
};
28+
29+
class RootedContainer {
30+
Rooted<void*> root;
31+
};

0 commit comments

Comments
 (0)