summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--book/src/blacklisting.md4
-rw-r--r--src/codegen/derive_debug.rs10
-rw-r--r--src/ir/analysis/derive_copy.rs32
-rw-r--r--src/ir/analysis/derive_debug.rs38
-rw-r--r--src/ir/analysis/derive_default.rs79
-rw-r--r--src/ir/analysis/derive_hash.rs4
-rw-r--r--src/ir/analysis/derive_partial_eq.rs4
-rw-r--r--src/ir/dot.rs22
-rw-r--r--src/ir/ty.rs8
-rw-r--r--tests/expectations/tests/blacklist-and-impl-debug.rs34
-rw-r--r--tests/expectations/tests/derive-default-and-blacklist.rs30
-rw-r--r--tests/expectations/tests/derive-hash-and-blacklist.rs28
-rw-r--r--tests/expectations/tests/derive-hash-blacklisting.rs8
-rw-r--r--tests/expectations/tests/derive-partialeq-and-blacklist.rs30
-rw-r--r--tests/expectations/tests/doggo-or-null.rs65
-rw-r--r--tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs9
-rw-r--r--tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs1
-rw-r--r--tests/expectations/tests/issue-662-part-2.rs1
-rw-r--r--tests/expectations/tests/issue-944-derive-copy-and-blacklisting.rs27
-rw-r--r--tests/expectations/tests/no-derive-debug.rs4
-rw-r--r--tests/expectations/tests/no-derive-default.rs4
-rw-r--r--tests/expectations/tests/no-recursive-whitelisting.rs4
-rw-r--r--tests/expectations/tests/opaque-template-inst-member.rs2
-rw-r--r--tests/headers/blacklist-and-impl-debug.hpp10
-rw-r--r--tests/headers/derive-default-and-blacklist.hpp14
-rw-r--r--tests/headers/derive-hash-and-blacklist.hpp10
-rw-r--r--tests/headers/derive-partialeq-and-blacklist.hpp11
-rw-r--r--tests/headers/doggo-or-null.hpp20
-rw-r--r--tests/headers/issue-944-derive-copy-and-blacklisting.hpp10
29 files changed, 425 insertions, 98 deletions
diff --git a/book/src/blacklisting.md b/book/src/blacklisting.md
index 990947ab..3553d8b2 100644
--- a/book/src/blacklisting.md
+++ b/book/src/blacklisting.md
@@ -8,6 +8,10 @@ appear in the bindings at
all, [make it opaque](./opaque.html) instead of
blacklisting it.)
+Blacklisted types are pessimistically assumed not to be able to `derive` any
+traits, which can transitively affect other types' ability to `derive` traits or
+not.
+
### Library
* [`bindgen::Builder::hide_type`](https://docs.rs/bindgen/0.23.1/bindgen/struct.Builder.html#method.hide_type)
diff --git a/src/codegen/derive_debug.rs b/src/codegen/derive_debug.rs
index 066af339..82456797 100644
--- a/src/codegen/derive_debug.rs
+++ b/src/codegen/derive_debug.rs
@@ -53,7 +53,7 @@ pub fn gen_debug_impl(
impl X {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, $format_string $tokens)
- }
+ }
});
match impl_.unwrap().node {
@@ -127,6 +127,12 @@ impl<'a> ImplDebug<'a> for Item {
) -> Option<(String, Vec<TokenTree>)> {
let name_ident = ctx.rust_ident_raw(name);
+ // We don't know if blacklisted items `impl Debug` or not, so we can't
+ // add them to the format string we're building up.
+ if !ctx.whitelisted_items().contains(&self.id()) {
+ return None;
+ }
+
let ty = match self.as_type() {
Some(ty) => ty,
None => {
@@ -168,7 +174,7 @@ impl<'a> ImplDebug<'a> for Item {
} else {
debug_print(ctx, name, name_ident)
}
- }
+ }
// The generic is not required to implement Debug, so we can not debug print that type
TypeKind::TypeParam => {
diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs
index c108a961..1890dcec 100644
--- a/src/ir/analysis/derive_copy.rs
+++ b/src/ir/analysis/derive_copy.rs
@@ -88,6 +88,13 @@ impl<'ctx, 'gen> CannotDeriveCopy<'ctx, 'gen> {
ConstrainResult::Changed
}
+
+ /// A type is not `Copy` if we've determined it is not copy, or if it is
+ /// blacklisted.
+ fn is_not_copy(&self, id: ItemId) -> bool {
+ self.cannot_derive_copy.contains(&id) ||
+ !self.ctx.whitelisted_items().contains(&id)
+ }
}
impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
@@ -118,6 +125,15 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
return ConstrainResult::Same;
}
+ // If an item is reachable from the whitelisted items set, but isn't
+ // itself whitelisted, then it must be blacklisted. We assume that
+ // blacklisted items are not `Copy`, since they are presumably
+ // blacklisted because they are too complicated for us to understand.
+ if !self.ctx.whitelisted_items().contains(&id) {
+ trace!(" blacklisted items are assumed not to be Copy");
+ return ConstrainResult::Same;
+ }
+
let item = self.ctx.resolve_item(id);
let ty = match item.as_type() {
Some(ty) => ty,
@@ -163,7 +179,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
}
TypeKind::Array(t, len) => {
- let cant_derive_copy = self.cannot_derive_copy.contains(&t);
+ let cant_derive_copy = self.is_not_copy(t);
if cant_derive_copy {
trace!(
" arrays of T for which we cannot derive Copy \
@@ -184,7 +200,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- let cant_derive_copy = self.cannot_derive_copy.contains(&t);
+ let cant_derive_copy = self.is_not_copy(t);
if cant_derive_copy {
trace!(
" arrays of T for which we cannot derive Copy \
@@ -237,7 +253,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
- self.cannot_derive_copy.contains(&base.ty)
+ self.is_not_copy(base.ty)
});
if bases_cannot_derive {
trace!(
@@ -250,11 +266,11 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
let fields_cannot_derive =
info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
- self.cannot_derive_copy.contains(&data.ty())
+ self.is_not_copy(data.ty())
}
Field::Bitfields(ref bfu) => {
bfu.bitfields().iter().any(|b| {
- self.cannot_derive_copy.contains(&b.ty())
+ self.is_not_copy(b.ty())
})
}
});
@@ -270,7 +286,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
TypeKind::TemplateInstantiation(ref template) => {
let args_cannot_derive =
template.template_arguments().iter().any(|arg| {
- self.cannot_derive_copy.contains(&arg)
+ self.is_not_copy(*arg)
});
if args_cannot_derive {
trace!(
@@ -284,8 +300,8 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveCopy<'ctx, 'gen> {
!template.template_definition().is_opaque(self.ctx, &()),
"The early ty.is_opaque check should have handled this case"
);
- let def_cannot_derive = self.cannot_derive_copy.contains(
- &template.template_definition(),
+ let def_cannot_derive = self.is_not_copy(
+ template.template_definition(),
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs
index 14630155..b7a35132 100644
--- a/src/ir/analysis/derive_debug.rs
+++ b/src/ir/analysis/derive_debug.rs
@@ -90,6 +90,13 @@ impl<'ctx, 'gen> CannotDeriveDebug<'ctx, 'gen> {
ConstrainResult::Changed
}
+
+ /// A type is not `Debug` if we've determined it is not debug, or if it is
+ /// blacklisted.
+ fn is_not_debug(&self, id: ItemId) -> bool {
+ self.cannot_derive_debug.contains(&id) ||
+ !self.ctx.whitelisted_items().contains(&id)
+ }
}
impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
@@ -120,6 +127,15 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
return ConstrainResult::Same;
}
+ // If an item is reachable from the whitelisted items set, but isn't
+ // itself whitelisted, then it must be blacklisted. We assume that
+ // blacklisted items are not `Copy`, since they are presumably
+ // blacklisted because they are too complicated for us to understand.
+ if !self.ctx.whitelisted_items().contains(&id) {
+ trace!(" blacklisted items are assumed not to be Debug");
+ return ConstrainResult::Same;
+ }
+
let item = self.ctx.resolve_item(id);
let ty = match item.as_type() {
Some(ty) => ty,
@@ -129,11 +145,13 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
}
};
- if ty.is_opaque(self.ctx, item) {
+ if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_debug()
});
- return if layout_can_derive {
+ return if layout_can_derive &&
+ !(ty.is_union() &&
+ self.ctx.options().rust_features().untagged_union()) {
trace!(" we can trivially derive Debug for the layout");
ConstrainResult::Same
} else {
@@ -176,7 +194,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_debug.contains(&t) {
+ if self.is_not_debug(t) {
trace!(
" arrays of T for which we cannot derive Debug \
also cannot derive Debug"
@@ -196,7 +214,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.cannot_derive_debug.contains(&t) {
+ if self.is_not_debug(t) {
trace!(
" aliases and type refs to T which cannot derive \
Debug also cannot derive Debug"
@@ -237,7 +255,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
- self.cannot_derive_debug.contains(&base.ty)
+ self.is_not_debug(base.ty)
});
if bases_cannot_derive {
trace!(
@@ -250,11 +268,11 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
let fields_cannot_derive =
info.fields().iter().any(|f| match *f {
Field::DataMember(ref data) => {
- self.cannot_derive_debug.contains(&data.ty())
+ self.is_not_debug(data.ty())
}
Field::Bitfields(ref bfu) => {
bfu.bitfields().iter().any(|b| {
- self.cannot_derive_debug.contains(&b.ty())
+ self.is_not_debug(b.ty())
})
}
});
@@ -287,7 +305,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
TypeKind::TemplateInstantiation(ref template) => {
let args_cannot_derive =
template.template_arguments().iter().any(|arg| {
- self.cannot_derive_debug.contains(&arg)
+ self.is_not_debug(*arg)
});
if args_cannot_derive {
trace!(
@@ -301,8 +319,8 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
!template.template_definition().is_opaque(self.ctx, &()),
"The early ty.is_opaque check should have handled this case"
);
- let def_cannot_derive = self.cannot_derive_debug.contains(
- &template.template_definition(),
+ let def_cannot_derive = self.is_not_debug(
+ template.template_definition(),
);
if def_cannot_derive {
trace!(
diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs
index 74e05cd6..19f4a842 100644
--- a/src/ir/analysis/derive_default.rs
+++ b/src/ir/analysis/derive_default.rs
@@ -87,6 +87,11 @@ impl<'ctx, 'gen> CannotDeriveDefault<'ctx, 'gen> {
ConstrainResult::Changed
}
+
+ fn is_not_default(&self, id: ItemId) -> bool {
+ self.cannot_derive_default.contains(&id) ||
+ !self.ctx.whitelisted_items().contains(&id)
+ }
}
impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
@@ -153,6 +158,11 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
return ConstrainResult::Same;
}
+ if !self.ctx.whitelisted_items().contains(&id) {
+ trace!(" blacklisted items pessimistically cannot derive Default");
+ return ConstrainResult::Same;
+ }
+
let item = self.ctx.resolve_item(id);
let ty = match item.as_type() {
Some(ty) => ty,
@@ -166,7 +176,9 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_default()
});
- return if layout_can_derive {
+ return if layout_can_derive &&
+ !(ty.is_union() &&
+ self.ctx.options().rust_features().untagged_union()) {
trace!(" we can trivially derive Default for the layout");
ConstrainResult::Same
} else {
@@ -213,7 +225,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_default.contains(&t) {
+ if self.is_not_default(t) {
trace!(
" arrays of T for which we cannot derive Default \
also cannot derive Default"
@@ -233,7 +245,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.cannot_derive_default.contains(&t) {
+ if self.is_not_default(t) {
trace!(
" aliases and type refs to T which cannot derive \
Default also cannot derive Default"
@@ -280,7 +292,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
!self.ctx.whitelisted_items().contains(&base.ty) ||
- self.cannot_derive_default.contains(&base.ty)
+ self.is_not_default(base.ty)
});
if bases_cannot_derive {
trace!(
@@ -296,14 +308,14 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
!self.ctx.whitelisted_items().contains(
&data.ty(),
) ||
- self.cannot_derive_default.contains(&data.ty())
+ self.is_not_default(data.ty())
}
Field::Bitfields(ref bfu) => {
bfu.bitfields().iter().any(|b| {
!self.ctx.whitelisted_items().contains(
&b.ty(),
) ||
- self.cannot_derive_default.contains(&b.ty())
+ self.is_not_default(b.ty())
})
}
});
@@ -319,45 +331,34 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
}
TypeKind::TemplateInstantiation(ref template) => {
- if self.ctx.whitelisted_items().contains(
- &template.template_definition(),
- )
- {
- let args_cannot_derive =
- template.template_arguments().iter().any(|arg| {
- self.cannot_derive_default.contains(&arg)
- });
- if args_cannot_derive {
- trace!(
- " template args cannot derive Default, so \
- insantiation can't either"
- );
- return self.insert(id);
- }
-
- assert!(
- !template.template_definition().is_opaque(self.ctx, &()),
- "The early ty.is_opaque check should have handled this case"
+ let args_cannot_derive =
+ template.template_arguments().iter().any(|arg| {
+ self.is_not_default(*arg)
+ });
+ if args_cannot_derive {
+ trace!(
+ " template args cannot derive Default, so \
+ insantiation can't either"
);
- let def_cannot_derive =
- self.cannot_derive_default.contains(&template
- .template_definition());
- if def_cannot_derive {
- trace!(
- " template definition cannot derive Default, so \
- insantiation can't either"
- );
- return self.insert(id);
- }
+ return self.insert(id);
+ }
- trace!(" template instantiation can derive Default");
- ConstrainResult::Same
- } else {
+ assert!(
+ !template.template_definition().is_opaque(self.ctx, &()),
+ "The early ty.is_opaque check should have handled this case"
+ );
+ let def_cannot_derive =
+ self.is_not_default(template.template_definition());
+ if def_cannot_derive {
trace!(
- " blacklisted template instantiation cannot derive default"
+ " template definition cannot derive Default, so \
+ insantiation can't either"
);
return self.insert(id);
}
+
+ trace!(" template instantiation can derive Default");
+ ConstrainResult::Same
}
TypeKind::Opaque => {
diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs
index d0ab3762..ee9cb23a 100644
--- a/src/ir/analysis/derive_hash.rs
+++ b/src/ir/analysis/derive_hash.rs
@@ -133,7 +133,9 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveHash<'ctx, 'gen> {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_hash()
});
- return if layout_can_derive {
+ return if layout_can_derive &&
+ !(ty.is_union() &&
+ self.ctx.options().rust_features().untagged_union()) {
trace!(" we can trivially derive Hash for the layout");
ConstrainResult::Same
} else {
diff --git a/src/ir/analysis/derive_partial_eq.rs b/src/ir/analysis/derive_partial_eq.rs
index 030c4c48..45ba67a5 100644
--- a/src/ir/analysis/derive_partial_eq.rs
+++ b/src/ir/analysis/derive_partial_eq.rs
@@ -136,7 +136,9 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDerivePartialEq<'ctx, 'gen> {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_partialeq()
});
- return if layout_can_derive {
+ return if layout_can_derive &&
+ !(ty.is_union() &&
+ self.ctx.options().rust_features().untagged_union()) {
trace!(" we can trivially derive PartialEq for the layout");
ConstrainResult::Same
} else {
diff --git a/src/ir/dot.rs b/src/ir/dot.rs
index 6d666f09..1181c32c 100644
--- a/src/ir/dot.rs
+++ b/src/ir/dot.rs
@@ -32,10 +32,17 @@ where
let mut err: Option<io::Result<_>> = None;
for (id, item) in ctx.items() {
+ let is_whitelisted = ctx.whitelisted_items().contains(id);
+
try!(writeln!(
&mut dot_file,
- r#"{} [fontname="courier", label=< <table border="0" align="left">"#,
- id.as_usize()
+ r#"{} [fontname="courier", color={}, label=< <table border="0" align="left">"#,
+ id.as_usize(),
+ if is_whitelisted {
+ "black"
+ } else {
+ "gray"
+ }
));
try!(item.dot_attributes(ctx, &mut dot_file));
try!(writeln!(&mut dot_file, r#"</table> >];"#));
@@ -49,10 +56,15 @@ where
match writeln!(
&mut dot_file,
- "{} -> {} [label={:?}];",
+ "{} -> {} [label={:?}, color={}];",
id.as_usize(),
sub_id.as_usize(),
- edge_kind
+ edge_kind,
+ if is_whitelisted {
+ "black"
+ } else {
+ "gray"
+ }
) {
Ok(_) => {}
Err(e) => err = Some(Err(e)),
@@ -69,7 +81,7 @@ where
for child in module.children() {
try!(writeln!(
&mut dot_file,
- "{} -> {} [style=dotted]",
+ "{} -> {} [style=dotted, color=gray]",
item.id().as_usize(),
child.as_usize()
));
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index da1cc6d7..b588dbb4 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -99,6 +99,14 @@ impl Type {
}
}
+ /// Is this a union?
+ pub fn is_union(&self) -> bool {
+ match self.kind {
+ TypeKind::Comp(ref comp) => comp.is_union(),
+ _ => false,
+ }
+ }
+
/// Is this type of kind `TypeKind::TypeParam`?
pub fn is_type_param(&self) -> bool {
match self.kind {
diff --git a/tests/expectations/tests/blacklist-and-impl-debug.rs b/tests/expectations/tests/blacklist-and-impl-debug.rs
new file mode 100644
index 00000000..d84b0256
--- /dev/null
+++ b/tests/expectations/tests/blacklist-and-impl-debug.rs
@@ -0,0 +1,34 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive Debug.
+#[repr(C)]
+pub struct ShouldManuallyImplDebug {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldManuallyImplDebug() {
+ assert_eq!(::std::mem::size_of::<ShouldManuallyImplDebug>() , 1usize ,
+ concat ! (
+ "Size of: " , stringify ! ( ShouldManuallyImplDebug ) ));
+ assert_eq! (::std::mem::align_of::<ShouldManuallyImplDebug>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ShouldManuallyImplDebug ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldManuallyImplDebug ) ) . a as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ShouldManuallyImplDebug
+ ) , "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldManuallyImplDebug {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+impl ::std::fmt::Debug for ShouldManuallyImplDebug {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f , "ShouldManuallyImplDebug {{ }}")
+ }
+}
diff --git a/tests/expectations/tests/derive-default-and-blacklist.rs b/tests/expectations/tests/derive-default-and-blacklist.rs
new file mode 100644
index 00000000..e811bd05
--- /dev/null
+++ b/tests/expectations/tests/derive-default-and-blacklist.rs
@@ -0,0 +1,30 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive
+/// Default. Instead, we should emit a `mem::zeroed` implementation.
+#[repr(C)]
+pub struct ShouldNotDeriveDefault {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotDeriveDefault() {
+ assert_eq!(::std::mem::size_of::<ShouldNotDeriveDefault>() , 1usize ,
+ concat ! ( "Size of: " , stringify ! ( ShouldNotDeriveDefault )
+ ));
+ assert_eq! (::std::mem::align_of::<ShouldNotDeriveDefault>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ShouldNotDeriveDefault ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldNotDeriveDefault ) ) . a as * const
+ _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ShouldNotDeriveDefault
+ ) , "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldNotDeriveDefault {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/expectations/tests/derive-hash-and-blacklist.rs b/tests/expectations/tests/derive-hash-and-blacklist.rs
new file mode 100644
index 00000000..e5a66376
--- /dev/null
+++ b/tests/expectations/tests/derive-hash-and-blacklist.rs
@@ -0,0 +1,28 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive Hash.
+#[repr(C)]
+pub struct ShouldNotDeriveHash {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotDeriveHash() {
+ assert_eq!(::std::mem::size_of::<ShouldNotDeriveHash>() , 1usize , concat
+ ! ( "Size of: " , stringify ! ( ShouldNotDeriveHash ) ));
+ assert_eq! (::std::mem::align_of::<ShouldNotDeriveHash>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ShouldNotDeriveHash ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldNotDeriveHash ) ) . a as * const _
+ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ShouldNotDeriveHash ) ,
+ "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldNotDeriveHash {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/expectations/tests/derive-hash-blacklisting.rs b/tests/expectations/tests/derive-hash-blacklisting.rs
index d24586be..5d1a8d37 100644
--- a/tests/expectations/tests/derive-hash-blacklisting.rs
+++ b/tests/expectations/tests/derive-hash-blacklisting.rs
@@ -8,7 +8,6 @@
/// This would derive(Hash, Eq, PartialEq) if it didn't contain a blacklisted type,
/// causing us to conservatively avoid deriving hash/Eq/PartialEq for it.
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct WhitelistedOne {
pub a: Blacklisted<::std::os::raw::c_int>,
}
@@ -24,15 +23,11 @@ fn bindgen_test_layout_WhitelistedOne() {
"Alignment of field: " , stringify ! ( WhitelistedOne ) , "::"
, stringify ! ( a ) ));
}
-impl Clone for WhitelistedOne {
- fn clone(&self) -> Self { *self }
-}
impl Default for WhitelistedOne {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
/// This can't derive(Hash/Eq) even if it didn't contain a blacklisted type.
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct WhitelistedTwo {
pub b: Blacklisted<f32>,
}
@@ -48,9 +43,6 @@ fn bindgen_test_layout_WhitelistedTwo() {
"Alignment of field: " , stringify ! ( WhitelistedTwo ) , "::"
, stringify ! ( b ) ));
}
-impl Clone for WhitelistedTwo {
- fn clone(&self) -> Self { *self }
-}
impl Default for WhitelistedTwo {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
diff --git a/tests/expectations/tests/derive-partialeq-and-blacklist.rs b/tests/expectations/tests/derive-partialeq-and-blacklist.rs
new file mode 100644
index 00000000..4aac3c8c
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-and-blacklist.rs
@@ -0,0 +1,30 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive
+/// PartialEq.
+#[repr(C)]
+pub struct ShouldNotDerivePartialEq {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotDerivePartialEq() {
+ assert_eq!(::std::mem::size_of::<ShouldNotDerivePartialEq>() , 1usize ,
+ concat ! (
+ "Size of: " , stringify ! ( ShouldNotDerivePartialEq ) ));
+ assert_eq! (::std::mem::align_of::<ShouldNotDerivePartialEq>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ShouldNotDerivePartialEq ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldNotDerivePartialEq ) ) . a as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! (
+ ShouldNotDerivePartialEq ) , "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldNotDerivePartialEq {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/expectations/tests/doggo-or-null.rs b/tests/expectations/tests/doggo-or-null.rs
new file mode 100644
index 00000000..292533d9
--- /dev/null
+++ b/tests/expectations/tests/doggo-or-null.rs
@@ -0,0 +1,65 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, Copy, Hash, PartialEq)]
+pub struct Doggo {
+ pub x: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_Doggo() {
+ assert_eq!(::std::mem::size_of::<Doggo>() , 4usize , concat ! (
+ "Size of: " , stringify ! ( Doggo ) ));
+ assert_eq! (::std::mem::align_of::<Doggo>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( Doggo ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const Doggo ) ) . x as * const _ as usize } ,
+ 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( Doggo ) , "::" ,
+ stringify ! ( x ) ));
+}
+impl Clone for Doggo {
+ fn clone(&self) -> Self { *self }
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy, Hash, PartialEq)]
+pub struct Null {
+ pub _address: u8,
+}
+#[test]
+fn bindgen_test_layout_Null() {
+ assert_eq!(::std::mem::size_of::<Null>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( Null ) ));
+ assert_eq! (::std::mem::align_of::<Null>() , 1usize , concat ! (
+ "Alignment of " , stringify ! ( Null ) ));
+}
+impl Clone for Null {
+ fn clone(&self) -> Self { *self }
+}
+/// This type is an opaque union. Unions can't derive anything interesting like
+/// Debug or Default, even if their layout can, because it would require knowing
+/// which variant is in use. Opaque unions still end up as a `union` in the Rust
+/// bindings, but they just have one variant. Even so, can't derive. We should
+/// probably emit an opaque struct for opaque unions... but until then, we have
+/// this test to make sure that opaque unions don't derive and still compile.
+#[repr(C)]
+#[derive(Copy)]
+pub union DoggoOrNull {
+ pub _bindgen_opaque_blob: u32,
+}
+#[test]
+fn bindgen_test_layout_DoggoOrNull() {
+ assert_eq!(::std::mem::size_of::<DoggoOrNull>() , 4usize , concat ! (
+ "Size of: " , stringify ! ( DoggoOrNull ) ));
+ assert_eq! (::std::mem::align_of::<DoggoOrNull>() , 4usize , concat ! (
+ "Alignment of " , stringify ! ( DoggoOrNull ) ));
+}
+impl Clone for DoggoOrNull {
+ fn clone(&self) -> Self { *self }
+}
+impl Default for DoggoOrNull {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs b/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs
index 540b5e7f..d0ccacef 100644
--- a/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs
+++ b/tests/expectations/tests/issue-584-stylo-template-analysis-panic.rs
@@ -22,7 +22,6 @@ impl Clone for A {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
pub struct e<c> {
pub d: RefPtr<c>,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<c>>,
@@ -36,7 +35,6 @@ pub struct f {
pub _address: u8,
}
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct g {
pub h: f,
}
@@ -51,14 +49,10 @@ fn bindgen_test_layout_g() {
"Alignment of field: " , stringify ! ( g ) , "::" , stringify
! ( h ) ));
}
-impl Clone for g {
- fn clone(&self) -> Self { *self }
-}
impl Default for g {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct b {
pub _base: g,
}
@@ -69,9 +63,6 @@ fn bindgen_test_layout_b() {
assert_eq! (::std::mem::align_of::<b>() , 1usize , concat ! (
"Alignment of " , stringify ! ( b ) ));
}
-impl Clone for b {
- fn clone(&self) -> Self { *self }
-}
impl Default for b {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
diff --git a/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs b/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs
index d705ffa3..87228ec6 100644
--- a/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs
+++ b/tests/expectations/tests/issue-645-cannot-find-type-T-in-this-scope.rs
@@ -6,7 +6,6 @@
#[derive(Clone, Copy, Debug)] pub struct RefPtr<T>(T);
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
pub struct HasRefPtr<T> {
pub refptr_member: RefPtr<HasRefPtr_TypedefOfT<T>>,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
diff --git a/tests/expectations/tests/issue-662-part-2.rs b/tests/expectations/tests/issue-662-part-2.rs
index 8225cf18..a1b97ca6 100644
--- a/tests/expectations/tests/issue-662-part-2.rs
+++ b/tests/expectations/tests/issue-662-part-2.rs
@@ -15,7 +15,6 @@ impl <T> Default for nsMainThreadPtrHolder<T> {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
pub struct nsMainThreadPtrHandle<U> {
pub mPtr: RefPtr<nsMainThreadPtrHolder<U>>,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<U>>,
diff --git a/tests/expectations/tests/issue-944-derive-copy-and-blacklisting.rs b/tests/expectations/tests/issue-944-derive-copy-and-blacklisting.rs
new file mode 100644
index 00000000..10e54056
--- /dev/null
+++ b/tests/expectations/tests/issue-944-derive-copy-and-blacklisting.rs
@@ -0,0 +1,27 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive Copy.
+#[repr(C)]
+pub struct ShouldNotBeCopy {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotBeCopy() {
+ assert_eq!(::std::mem::size_of::<ShouldNotBeCopy>() , 1usize , concat ! (
+ "Size of: " , stringify ! ( ShouldNotBeCopy ) ));
+ assert_eq! (::std::mem::align_of::<ShouldNotBeCopy>() , 1usize , concat !
+ ( "Alignment of " , stringify ! ( ShouldNotBeCopy ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldNotBeCopy ) ) . a as * const _ as
+ usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ShouldNotBeCopy ) ,
+ "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldNotBeCopy {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/expectations/tests/no-derive-debug.rs b/tests/expectations/tests/no-derive-debug.rs
index 311b3767..f1616e64 100644
--- a/tests/expectations/tests/no-derive-debug.rs
+++ b/tests/expectations/tests/no-derive-debug.rs
@@ -9,7 +9,6 @@
/// and replacement for another type that doesn't implement it would prevent it
/// from building if --no-derive-debug didn't work.
#[repr(C)]
-#[derive(Copy)]
pub struct bar {
pub foo: foo,
pub baz: ::std::os::raw::c_int,
@@ -31,9 +30,6 @@ fn bindgen_test_layout_bar() {
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( baz ) ));
}
-impl Clone for bar {
- fn clone(&self) -> Self { *self }
-}
impl Default for bar {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
diff --git a/tests/expectations/tests/no-derive-default.rs b/tests/expectations/tests/no-derive-default.rs
index c212f4bd..cdb89eb1 100644
--- a/tests/expectations/tests/no-derive-default.rs
+++ b/tests/expectations/tests/no-derive-default.rs
@@ -9,7 +9,6 @@
/// and replacement for another type that doesn't implement it would prevent it
/// from building if --no-derive-default didn't work.
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct bar {
pub foo: foo,
pub baz: ::std::os::raw::c_int,
@@ -31,6 +30,3 @@ fn bindgen_test_layout_bar() {
"Alignment of field: " , stringify ! ( bar ) , "::" ,
stringify ! ( baz ) ));
}
-impl Clone for bar {
- fn clone(&self) -> Self { *self }
-}
diff --git a/tests/expectations/tests/no-recursive-whitelisting.rs b/tests/expectations/tests/no-recursive-whitelisting.rs
index e2aba543..30dc9e69 100644
--- a/tests/expectations/tests/no-recursive-whitelisting.rs
+++ b/tests/expectations/tests/no-recursive-whitelisting.rs
@@ -6,7 +6,6 @@
pub enum Bar {}
#[repr(C)]
-#[derive(Debug, Copy)]
pub struct Foo {
pub baz: *mut Bar,
}
@@ -22,9 +21,6 @@ fn bindgen_test_layout_Foo() {
"Alignment of field: " , stringify ! ( Foo ) , "::" ,
stringify ! ( baz ) ));
}
-impl Clone for Foo {
- fn clone(&self) -> Self { *self }
-}
impl Default for Foo {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
diff --git a/tests/expectations/tests/opaque-template-inst-member.rs b/tests/expectations/tests/opaque-template-inst-member.rs
index 32995873..0bef4c86 100644
--- a/tests/expectations/tests/opaque-template-inst-member.rs
+++ b/tests/expectations/tests/opaque-template-inst-member.rs
@@ -5,7 +5,7 @@
#[repr(C)]
-#[derive(Default, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
pub struct OpaqueTemplate {
}
/// This should not end up deriving Debug/Hash/PartialEq because its `mBlah` field cannot derive
diff --git a/tests/headers/blacklist-and-impl-debug.hpp b/tests/headers/blacklist-and-impl-debug.hpp
new file mode 100644
index 00000000..b4b39fe4
--- /dev/null
+++ b/tests/headers/blacklist-and-impl-debug.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --impl-debug --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive Debug.
+ */
+struct ShouldManuallyImplDebug {
+ BlacklistMe a;
+};
diff --git a/tests/headers/derive-default-and-blacklist.hpp b/tests/headers/derive-default-and-blacklist.hpp
new file mode 100644
index 00000000..7a2b7505
--- /dev/null
+++ b/tests/headers/derive-default-and-blacklist.hpp
@@ -0,0 +1,14 @@
+// bindgen-flags: --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+// Note that we do not explicitly provide the `--with-derive-default` flag
+// above, since it is added by the test runner implicitly.
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive
+ * Default. Instead, we should emit a `mem::zeroed` implementation.
+ */
+struct ShouldNotDeriveDefault {
+ BlacklistMe a;
+};
diff --git a/tests/headers/derive-hash-and-blacklist.hpp b/tests/headers/derive-hash-and-blacklist.hpp
new file mode 100644
index 00000000..4b3a4a53
--- /dev/null
+++ b/tests/headers/derive-hash-and-blacklist.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --with-derive-hash --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive Hash.
+ */
+struct ShouldNotDeriveHash {
+ BlacklistMe a;
+};
diff --git a/tests/headers/derive-partialeq-and-blacklist.hpp b/tests/headers/derive-partialeq-and-blacklist.hpp
new file mode 100644
index 00000000..a996eee8
--- /dev/null
+++ b/tests/headers/derive-partialeq-and-blacklist.hpp
@@ -0,0 +1,11 @@
+// bindgen-flags: --with-derive-partialeq --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive
+ * PartialEq.
+ */
+struct ShouldNotDerivePartialEq {
+ BlacklistMe a;
+};
diff --git a/tests/headers/doggo-or-null.hpp b/tests/headers/doggo-or-null.hpp
new file mode 100644
index 00000000..9146e189
--- /dev/null
+++ b/tests/headers/doggo-or-null.hpp
@@ -0,0 +1,20 @@
+// bindgen-flags: --opaque-type DoggoOrNull --with-derive-partialeq --with-derive-hash -- -std=c++14
+
+class Doggo {
+ int x;
+};
+
+class Null {};
+
+/**
+ * This type is an opaque union. Unions can't derive anything interesting like
+ * Debug or Default, even if their layout can, because it would require knowing
+ * which variant is in use. Opaque unions still end up as a `union` in the Rust
+ * bindings, but they just have one variant. Even so, can't derive. We should
+ * probably emit an opaque struct for opaque unions... but until then, we have
+ * this test to make sure that opaque unions don't derive and still compile.
+ */
+union DoggoOrNull {
+ Doggo doggo;
+ Null none;
+};
diff --git a/tests/headers/issue-944-derive-copy-and-blacklisting.hpp b/tests/headers/issue-944-derive-copy-and-blacklisting.hpp
new file mode 100644
index 00000000..657e0d84
--- /dev/null
+++ b/tests/headers/issue-944-derive-copy-and-blacklisting.hpp
@@ -0,0 +1,10 @@
+// bindgen-flags: --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive Copy.
+ */
+struct ShouldNotBeCopy {
+ BlacklistMe a;
+};