diff options
author | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-04-16 05:26:32 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-04-16 05:36:45 +0200 |
commit | ca9f853fba5cace90febb52ea4a16d6a4ae394ca (patch) | |
tree | 99d37c5d0888ec14e33573d9b9cb3dc91e8485f6 | |
parent | 4a8fea550823afe97bd8b64c9aaf2171a9d4dcc2 (diff) |
types: Fix can_derive_copy() in edge cases
-rw-r--r-- | src/types.rs | 32 | ||||
-rw-r--r-- | tests/expectations/class_nested.rs | 2 | ||||
-rw-r--r-- | tests/expectations/template.rs | 20 | ||||
-rw-r--r-- | tests/expectations/using.rs | 2 | ||||
-rw-r--r-- | tests/headers/template.hpp | 11 |
5 files changed, 62 insertions, 5 deletions
diff --git a/src/types.rs b/src/types.rs index 120a455b..6e62fb98 100644 --- a/src/types.rs +++ b/src/types.rs @@ -235,10 +235,36 @@ impl Type { } } - fn can_derive_copy(&self) -> bool { - !self.is_opaque() && match *self { + // For some reason, deriving copies of an array of a type that is not known to be copy + // is a compile error. e.g.: + // + // #[derive(Copy)] + // struct A<T> { + // member: T, + // } + // + // is fine, while: + // + // #[derive(Copy)] + // struct A<T> { + // member: [T; 1], + // } + // + // is an error. + // + // That's the point of the existance of can_derive_copy_in_array(). + pub fn can_derive_copy_in_array(&self) -> bool { + match *self { TVoid => false, - TArray(ref t, _, _) => t.can_derive_copy(), + TNamed(ref ti) => ti.borrow().ty.can_derive_copy_in_array(), + TArray(ref t, _, _) => t.can_derive_copy_in_array(), + ref t => t.can_derive_copy(), + } + } + + pub fn can_derive_copy(&self) -> bool { + !self.is_opaque() && match *self { + TArray(ref t, _, _) => t.can_derive_copy_in_array(), TNamed(ref ti) => ti.borrow().ty.can_derive_copy(), TComp(ref comp) => comp.borrow().can_derive_copy(), _ => true, diff --git a/tests/expectations/class_nested.rs b/tests/expectations/class_nested.rs index ba23c3d3..0cec8d2e 100644 --- a/tests/expectations/class_nested.rs +++ b/tests/expectations/class_nested.rs @@ -45,7 +45,7 @@ fn bindgen_test_layout_Struct_D() { assert_eq!(::std::mem::align_of::<Struct_D>() , 4usize); } #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct Struct_Templated<T> { pub member: T, } diff --git a/tests/expectations/template.rs b/tests/expectations/template.rs index 35da356c..fb790d9b 100644 --- a/tests/expectations/template.rs +++ b/tests/expectations/template.rs @@ -27,6 +27,26 @@ pub struct Struct_D_U<T, Z> { pub m_baz: Z, pub _phantom0: ::std::marker::PhantomData<T>, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Struct_Rooted<T> { + pub prev: *mut T, + pub next: *mut T, + pub ptr: T, +} +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Struct_RootedContainer { + pub root: Struct_Rooted<*mut ::std::os::raw::c_void>, +} +impl ::std::clone::Clone for Struct_RootedContainer { + fn clone(&self) -> Self { *self } +} +#[test] +fn bindgen_test_layout_Struct_RootedContainer() { + assert_eq!(::std::mem::size_of::<Struct_RootedContainer>() , 24usize); + assert_eq!(::std::mem::align_of::<Struct_RootedContainer>() , 8usize); +} extern "C" { #[link_name = "_Z3bar3FooIiiE"] pub fn bar(foo: Struct_Foo<::std::os::raw::c_int, ::std::os::raw::c_int>); diff --git a/tests/expectations/using.rs b/tests/expectations/using.rs index 59201138..705c4bd5 100644 --- a/tests/expectations/using.rs +++ b/tests/expectations/using.rs @@ -6,7 +6,7 @@ #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct Struct_Point<T> { pub x: T, pub y: T, diff --git a/tests/headers/template.hpp b/tests/headers/template.hpp index d60f18fb..872d6e60 100644 --- a/tests/headers/template.hpp +++ b/tests/headers/template.hpp @@ -18,3 +18,14 @@ class D { Z m_baz; }; }; + +template<typename T> +class Rooted { + T* prev; + T* next; + T ptr; +}; + +class RootedContainer { + Rooted<void*> root; +}; |