summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <me@emiliocobos.me>2016-04-16 05:26:32 +0200
committerEmilio Cobos Álvarez <me@emiliocobos.me>2016-04-16 05:36:45 +0200
commitca9f853fba5cace90febb52ea4a16d6a4ae394ca (patch)
tree99d37c5d0888ec14e33573d9b9cb3dc91e8485f6
parent4a8fea550823afe97bd8b64c9aaf2171a9d4dcc2 (diff)
types: Fix can_derive_copy() in edge cases
-rw-r--r--src/types.rs32
-rw-r--r--tests/expectations/class_nested.rs2
-rw-r--r--tests/expectations/template.rs20
-rw-r--r--tests/expectations/using.rs2
-rw-r--r--tests/headers/template.hpp11
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;
+};