summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/impl_partialeq.rs121
-rw-r--r--src/codegen/mod.rs91
-rw-r--r--src/ir/analysis/derive_partial_eq_or_partial_ord.rs455
-rw-r--r--src/ir/analysis/mod.rs2
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/context.rs18
-rw-r--r--src/ir/derive.rs24
-rw-r--r--src/ir/function.rs13
-rw-r--r--src/ir/item.rs8
-rw-r--r--src/ir/layout.rs12
-rw-r--r--src/lib.rs45
-rw-r--r--src/options.rs16
-rw-r--r--tests/expectations/tests/class_1_0.rs404
-rw-r--r--tests/expectations/tests/derive-partialeq-anonfield.rs57
-rw-r--r--tests/expectations/tests/derive-partialeq-base.rs82
-rw-r--r--tests/expectations/tests/derive-partialeq-bitfield.rs130
-rw-r--r--tests/expectations/tests/derive-partialeq-core.rs50
-rw-r--r--tests/expectations/tests/derive-partialeq-pointer.rs129
-rw-r--r--tests/expectations/tests/derive-partialeq-union.rs56
-rw-r--r--tests/expectations/tests/derive-partialeq-union_1_0.rs104
-rw-r--r--tests/expectations/tests/issue-648-derive-debug-with-padding.rs10
-rw-r--r--tests/expectations/tests/layout_array.rs374
-rw-r--r--tests/expectations/tests/layout_array_too_long.rs318
-rw-r--r--tests/expectations/tests/opaque-template-inst-member.rs104
-rw-r--r--tests/headers/class_1_0.hpp2
-rw-r--r--tests/headers/derive-partialeq-anonfield.h5
-rw-r--r--tests/headers/derive-partialeq-base.hpp8
-rw-r--r--tests/headers/derive-partialeq-bitfield.hpp7
-rw-r--r--tests/headers/derive-partialeq-core.h5
-rw-r--r--tests/headers/derive-partialeq-pointer.hpp12
-rw-r--r--tests/headers/derive-partialeq-union.hpp7
-rw-r--r--tests/headers/derive-partialeq-union_1_0.hpp7
-rw-r--r--tests/headers/issue-648-derive-debug-with-padding.h2
-rw-r--r--tests/headers/layout_array.h2
-rw-r--r--tests/headers/layout_array_too_long.h2
-rw-r--r--tests/headers/opaque-template-inst-member.hpp8
36 files changed, 2021 insertions, 690 deletions
diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs
new file mode 100644
index 00000000..15a8953e
--- /dev/null
+++ b/src/codegen/impl_partialeq.rs
@@ -0,0 +1,121 @@
+
+use ir::comp::{CompInfo, CompKind, Field, FieldMethods};
+use ir::context::BindgenContext;
+use ir::item::{IsOpaque, Item};
+use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
+use quote;
+
+/// Generate a manual implementation of `PartialEq` trait for the
+/// specified compound type.
+pub fn gen_partialeq_impl(
+ ctx: &BindgenContext,
+ comp_info: &CompInfo,
+ item: &Item,
+ ty_for_impl: &quote::Tokens,
+) -> Option<quote::Tokens> {
+ let mut tokens = vec![];
+
+ if item.is_opaque(ctx, &()) {
+ tokens.push(quote! {
+ &self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..]
+ });
+ } else if comp_info.kind() == CompKind::Union {
+ tokens.push(quote! {
+ &self.bindgen_union_field[..] == &other.bindgen_union_field[..]
+ });
+ } else {
+ for base in comp_info.base_members().iter() {
+ if !base.requires_storage(ctx) {
+ continue;
+ }
+
+ let ty_item = ctx.resolve_item(base.ty);
+ let field_name = &base.field_name;
+
+ if ty_item.is_opaque(ctx, &()) {
+ let field_name = ctx.rust_ident(field_name);
+ tokens.push(quote! {
+ &self. #field_name [..] == &other. #field_name [..]
+ });
+ } else {
+ tokens.push(gen_field(ctx, ty_item, field_name));
+ }
+ }
+
+ for field in comp_info.fields() {
+ match *field {
+ Field::DataMember(ref fd) => {
+ let ty_item = ctx.resolve_item(fd.ty());
+ let name = fd.name().unwrap();
+ tokens.push(gen_field(ctx, ty_item, name));
+ }
+ Field::Bitfields(ref bu) => for bitfield in bu.bitfields() {
+ let name_ident = ctx.rust_ident_raw(bitfield.name());
+ tokens.push(quote! {
+ self.#name_ident () == other.#name_ident ()
+ });
+ },
+ }
+ }
+ }
+
+ Some(quote! {
+ fn eq(&self, other: & #ty_for_impl) -> bool {
+ #( #tokens )&&*
+ }
+ })
+}
+
+fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens {
+ fn quote_equals(name_ident: quote::Ident) -> quote::Tokens {
+ quote! { self.#name_ident == other.#name_ident }
+ }
+
+ let name_ident = ctx.rust_ident(name);
+ let ty = ty_item.expect_type();
+
+ match *ty.kind() {
+ TypeKind::Void |
+ TypeKind::NullPtr |
+ TypeKind::Int(..) |
+ TypeKind::Complex(..) |
+ TypeKind::Float(..) |
+ TypeKind::Enum(..) |
+ TypeKind::TypeParam |
+ TypeKind::UnresolvedTypeRef(..) |
+ TypeKind::BlockPointer |
+ TypeKind::Reference(..) |
+ TypeKind::ObjCInterface(..) |
+ TypeKind::ObjCId |
+ TypeKind::ObjCSel |
+ TypeKind::Comp(..) |
+ TypeKind::Pointer(_) |
+ TypeKind::Function(..) |
+ TypeKind::Opaque => quote_equals(name_ident),
+
+ TypeKind::TemplateInstantiation(ref inst) => {
+ if inst.is_opaque(ctx, &ty_item) {
+ quote! {
+ &self. #name_ident [..] == &other. #name_ident [..]
+ }
+ } else {
+ quote_equals(name_ident)
+ }
+ }
+
+ TypeKind::Array(_, len) => if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
+ quote_equals(name_ident)
+ } else {
+ quote! {
+ &self. #name_ident [..] == &other. #name_ident [..]
+ }
+ },
+
+ TypeKind::ResolvedTypeRef(t) |
+ TypeKind::TemplateAlias(t, _) |
+ TypeKind::Alias(t) => {
+ let inner_item = ctx.resolve_item(t);
+ gen_field(ctx, inner_item, name)
+ }
+ }
+}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 264b701b..9ccd79c1 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1,4 +1,5 @@
mod impl_debug;
+mod impl_partialeq;
mod error;
mod helpers;
pub mod struct_layout;
@@ -14,7 +15,7 @@ use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field,
use ir::context::{BindgenContext, ItemId};
use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
- CanDerivePartialEq, CanDeriveEq};
+ CanDerivePartialEq, CanDeriveEq, CannotDeriveReason};
use ir::dot;
use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue};
use ir::function::{Abi, Function, FunctionSig};
@@ -1420,6 +1421,7 @@ impl CodeGenerator for CompInfo {
let mut needs_clone_impl = false;
let mut needs_default_impl = false;
let mut needs_debug_impl = false;
+ let mut needs_partialeq_impl = false;
if let Some(comment) = item.comment(ctx) {
attributes.push(attributes::doc(comment));
}
@@ -1475,6 +1477,14 @@ impl CodeGenerator for CompInfo {
if item.can_derive_partialeq(ctx) {
derives.push("PartialEq");
+ } else {
+ needs_partialeq_impl =
+ ctx.options().derive_partialeq &&
+ ctx.options().impl_partialeq &&
+ ctx.lookup_can_derive_partialeq_or_partialord(item.id())
+ .map_or(true, |x| {
+ x == CannotDeriveReason::ArrayTooLarge
+ });
}
if item.can_derive_eq(ctx) {
@@ -1535,25 +1545,14 @@ impl CodeGenerator for CompInfo {
}
for base in self.base_members() {
- // Virtual bases are already taken into account by the vtable
- // pointer.
- //
- // FIXME(emilio): Is this always right?
- if base.is_virtual() {
- continue;
- }
-
- let base_ty = ctx.resolve_type(base.ty);
- // NB: We won't include unsized types in our base chain because they
- // would contribute to our size given the dummy field we insert for
- // unsized types.
- if base_ty.is_unsized(ctx, base.ty) {
+ if !base.requires_storage(ctx) {
continue;
}
let inner = base.ty.to_rust_ty_or_opaque(ctx, &());
let field_name = ctx.rust_ident(&base.field_name);
+ let base_ty = ctx.resolve_type(base.ty);
struct_layout.saw_base(base_ty);
fields.push(quote! {
@@ -1667,33 +1666,34 @@ impl CodeGenerator for CompInfo {
}
}
- let mut generics = quote! {};
+ let mut generic_param_names = vec![];
if let Some(ref params) = used_template_params {
- if !params.is_empty() {
- let mut param_names = vec![];
+ for (idx, ty) in params.iter().enumerate() {
+ let param = ctx.resolve_type(*ty);
+ let name = param.name().unwrap();
+ let ident = ctx.rust_ident(name);
+ generic_param_names.push(ident.clone());
- for (idx, ty) in params.iter().enumerate() {
- let param = ctx.resolve_type(*ty);
- let name = param.name().unwrap();
- let ident = ctx.rust_ident(name);
- param_names.push(ident.clone());
-
- let prefix = ctx.trait_prefix();
- let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
- fields.push(quote! {
- pub #field_name : ::#prefix::marker::PhantomData<
- ::#prefix::cell::UnsafeCell<#ident>
- > ,
- });
- }
-
- generics = quote! {
- < #( #param_names ),* >
- };
+ let prefix = ctx.trait_prefix();
+ let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
+ fields.push(quote! {
+ pub #field_name : ::#prefix::marker::PhantomData<
+ ::#prefix::cell::UnsafeCell<#ident>
+ > ,
+ });
}
}
+ let generics = if !generic_param_names.is_empty() {
+ let generic_param_names = generic_param_names.clone();
+ quote! {
+ < #( #generic_param_names ),* >
+ }
+ } else {
+ quote! { }
+ };
+
tokens.append(quote! {
#generics {
#( #fields )*
@@ -1896,6 +1896,27 @@ impl CodeGenerator for CompInfo {
});
}
+ if needs_partialeq_impl {
+ if let Some(impl_) = impl_partialeq::gen_partialeq_impl(ctx, self, item, &ty_for_impl) {
+
+ let partialeq_bounds = if !generic_param_names.is_empty() {
+ let bounds = generic_param_names.iter().map(|t| {
+ quote! { #t: PartialEq }
+ });
+ quote! { where #( #bounds ),* }
+ } else {
+ quote! { }
+ };
+
+ let prefix = ctx.trait_prefix();
+ result.push(quote! {
+ impl #generics ::#prefix::cmp::PartialEq for #ty_for_impl #partialeq_bounds {
+ #impl_
+ }
+ });
+ }
+ }
+
if !methods.is_empty() {
result.push(quote! {
impl #generics #ty_for_impl {
diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
index 7efce6e5..0cca6c6d 100644
--- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
+++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
@@ -3,16 +3,13 @@
use super::{ConstrainResult, MonotoneFramework, generate_dependencies};
use ir::comp::CompKind;
-use ir::comp::Field;
-use ir::comp::FieldMethods;
use ir::context::{BindgenContext, ItemId};
-use ir::derive::CanTriviallyDerivePartialEqOrPartialOrd;
-use ir::item::IsOpaque;
-use ir::traversal::EdgeKind;
+use ir::derive::{CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason};
+use ir::item::{Item, IsOpaque};
+use ir::traversal::{EdgeKind, Trace};
use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
-use ir::ty::TypeKind;
+use ir::ty::{TypeKind, Type};
use std::collections::HashMap;
-use std::collections::HashSet;
/// An analysis that finds for each IR item whether `PartialEq`/`PartialOrd`
/// cannot be derived.
@@ -23,9 +20,9 @@ use std::collections::HashSet;
/// * If T is Opaque and layout of the type is known, get this layout as opaque
/// type and check whether it can be derived using trivial checks.
///
-/// * If T is Array type, `PartialEq` or partialord cannot be derived if the
-/// length of the array is larger than the limit or the type of data the array
-/// contains cannot derive `PartialEq`/`PartialOrd`.
+/// * If T is Array type, `PartialEq` or partialord cannot be derived if the array is incomplete, if the length of
+/// the array is larger than the limit, or the type of data the array contains cannot derive
+/// `PartialEq`/`PartialOrd`.
///
/// * If T is a type alias, a templated alias or an indirection to another type,
/// `PartialEq`/`PartialOrd` cannot be derived if the type T refers to cannot be
@@ -47,7 +44,7 @@ pub struct CannotDerivePartialEqOrPartialOrd<'ctx> {
// The incremental result of this analysis's computation. Everything in this
// set cannot derive `PartialEq`/`PartialOrd`.
- cannot_derive_partialeq_or_partialord: HashSet<ItemId>,
+ cannot_derive_partialeq_or_partialord: HashMap<ItemId, CannotDeriveReason>,
// Dependencies saying that if a key ItemId has been inserted into the
// `cannot_derive_partialeq_or_partialord` set, then each of the ids
@@ -83,91 +80,66 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
}
}
- fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult {
+ fn insert<Id: Into<ItemId>>(
+ &mut self,
+ id: Id,
+ reason: CannotDeriveReason,
+ ) -> ConstrainResult {
let id = id.into();
- trace!("inserting {:?} into the cannot_derive_partialeq_or_partialord set", id);
-
- let was_not_already_in_set = self.cannot_derive_partialeq_or_partialord.insert(id);
- assert!(
- was_not_already_in_set,
- "We shouldn't try and insert {:?} twice because if it was \
- already in the set, `constrain` should have exited early.",
- id
+ trace!(
+ "inserting {:?} into the cannot_derive_partialeq_or_partialord because {:?}",
+ id,
+ reason
);
-
+ let existing = self.cannot_derive_partialeq_or_partialord
+ .insert(id, reason);
+ assert!(can_supersede(existing, Some(reason)));
ConstrainResult::Changed
}
-}
-
-impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
- type Node = ItemId;
- type Extra = &'ctx BindgenContext;
- type Output = HashSet<ItemId>;
-
- fn new(
- ctx: &'ctx BindgenContext,
- ) -> CannotDerivePartialEqOrPartialOrd<'ctx> {
- let cannot_derive_partialeq_or_partialord = HashSet::new();
- let dependencies = generate_dependencies(ctx, Self::consider_edge);
- CannotDerivePartialEqOrPartialOrd {
- ctx,
- cannot_derive_partialeq_or_partialord,
- dependencies,
+ fn constrain_type(
+ &mut self,
+ item: &Item,
+ ty: &Type,
+ ) -> Option<CannotDeriveReason> {
+ if !self.ctx.whitelisted_items().contains(&item.id()) {
+ return Some(CannotDeriveReason::Other);
}
- }
-
- fn initial_worklist(&self) -> Vec<ItemId> {
- self.ctx.whitelisted_items().iter().cloned().collect()
- }
-
- fn constrain(&mut self, id: ItemId) -> ConstrainResult {
- trace!("constrain: {:?}", id);
-
- if self.cannot_derive_partialeq_or_partialord.contains(&id) {
- trace!(" already know it cannot derive `PartialEq`/`PartialOrd`");
- return ConstrainResult::Same;
- }
-
- let item = self.ctx.resolve_item(id);
- let ty = match item.as_type() {
- Some(ty) => ty,
- None => {
- trace!(" not a type; ignoring");
- return ConstrainResult::Same;
- }
- };
if self.ctx.no_partialeq_by_name(&item) {
- return self.insert(id)
+ return Some(CannotDeriveReason::Other);
}
trace!("ty: {:?}", ty);
if item.is_opaque(self.ctx, &()) {
- let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
- l.opaque().can_trivially_derive_partialeq_or_partialord()
- });
- return if layout_can_derive &&
- !(ty.is_union() &&
- self.ctx.options().rust_features().untagged_union()) {
- trace!(" we can trivially derive `PartialEq`/`PartialOrd` for the layout");
- ConstrainResult::Same
- } else {
- trace!(" we cannot derive `PartialEq`/`PartialOrd` for the layout");
- self.insert(id)
- };
- }
+ if ty.is_union()
+ && self.ctx.options().rust_features().untagged_union()
+ {
+ trace!(
+ " cannot derive `PartialEq`/`PartialOrd` for Rust unions"
+ );
+ return Some(CannotDeriveReason::Other);
+ }
- if ty.layout(self.ctx).map_or(false, |l| {
- l.align > RUST_DERIVE_IN_ARRAY_LIMIT
- })
- {
- // We have to be conservative: the struct *could* have enough
- // padding that we emit an array that is longer than
- // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations
- // into the IR and computed them before this analysis, then we could
- // be precise rather than conservative here.
- return self.insert(id);
+ let layout_can_derive = ty.layout(self.ctx)
+ .map_or(CanDerive::Yes, |l| {
+ l.opaque().can_trivially_derive_partialeq_or_partialord()
+ });
+
+ return match layout_can_derive {
+ CanDerive::Yes => {
+ trace!(
+ " we can trivially derive `PartialEq`/`PartialOrd` for the layout"
+ );
+ None
+ }
+ CanDerive::No(reason) => {
+ trace!(
+ " we cannot derive `PartialEq`/`PartialOrd` for the layout"
+ );
+ Some(reason)
+ }
+ };
}
match *ty.kind() {
@@ -186,25 +158,36 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
TypeKind::ObjCSel => {
- trace!(" simple type that can always derive `PartialEq`/`PartialOrd`");
- ConstrainResult::Same
+ trace!(
+ " simple type that can always derive `PartialEq`/`PartialOrd`"
+ );
+ return None;
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) {
+ if self.cannot_derive_partialeq_or_partialord.contains_key(&t.into()) {
trace!(
" arrays of T for which we cannot derive `PartialEq`/`PartialOrd` \
- also cannot derive `PartialEq`/`PartialOrd`"
+ also cannot derive `PartialEq`/`PartialOrd`"
);
- return self.insert(id);
+ return Some(CannotDeriveReason::Other);
}
- if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
- trace!(" array is small enough to derive `PartialEq`/`PartialOrd`");
- ConstrainResult::Same
+ if len == 0 {
+ trace!(
+ " cannot derive `PartialEq`/`PartialOrd` for incomplete arrays"
+ );
+ return Some(CannotDeriveReason::Other);
+ } else if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
+ trace!(
+ " array is small enough to derive `PartialEq`/`PartialOrd`"
+ );
+ return None;
} else {
- trace!(" array is too large to derive `PartialEq`/`PartialOrd`");
- self.insert(id)
+ trace!(
+ " array is too large to derive `PartialEq`/`PartialOrd`"
+ );
+ return Some(CannotDeriveReason::ArrayTooLarge);
}
}
@@ -212,44 +195,30 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
let inner_type =
self.ctx.resolve_type(inner).canonical_type(self.ctx);
if let TypeKind::Function(ref sig) = *inner_type.kind() {
- if !sig.can_trivially_derive_partialeq_or_partialord() {
+ if let CanDerive::No(_) =
+ sig.can_trivially_derive_partialeq_or_partialord()
+ {
trace!(
" function pointer that can't trivially derive `PartialEq`/`PartialOrd`"
);
- return self.insert(id);
+ return Some(CannotDeriveReason::Other);
}
}
- trace!(" pointers can derive PartialEq");
- ConstrainResult::Same
+ trace!(" pointers can derive `PartialEq`/`PartialOrd`");
+ return None;
}
TypeKind::Function(ref sig) => {
- if !sig.can_trivially_derive_partialeq_or_partialord() {
+ if let CanDerive::No(_) =
+ sig.can_trivially_derive_partialeq_or_partialord()
+ {
trace!(
" function that can't trivially derive `PartialEq`/`PartialOrd`"
);
- return self.insert(id);
+ return Some(CannotDeriveReason::Other);
}
trace!(" function can derive `PartialEq`/`PartialOrd`");
- ConstrainResult::Same
- }
-
- TypeKind::ResolvedTypeRef(t) |
- TypeKind::TemplateAlias(t, _) |
- TypeKind::Alias(t) => {
- if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) {
- trace!(
- " aliases and type refs to T which cannot derive \
- `PartialEq`/`PartialOrd` also cannot derive `PartialEq`/`PartialOrd`"
- );
- self.insert(id)
- } else {
- trace!(
- " aliases and type refs to T which can derive \
- `PartialEq`/`PartialOrd` can also derive `PartialEq`/`PartialOrd`"
- );
- ConstrainResult::Same
- }
+ return None;
}
TypeKind::Comp(ref info) => {
@@ -260,114 +229,180 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
- trace!(" cannot derive `PartialEq`/`PartialOrd` for Rust unions");
- return self.insert(id);
- }
-
- if ty.layout(self.ctx).map_or(true, |l| {
- l.opaque().can_trivially_derive_partialeq_or_partialord()
- })
- {
trace!(
- " union layout can trivially derive `PartialEq`/`PartialOrd`"
+ " cannot derive `PartialEq`/`PartialOrd` for Rust unions"
);
- return ConstrainResult::Same;
- } else {
- trace!(" union layout cannot derive `PartialEq`/`PartialOrd`");
- return self.insert(id);
+ return Some(CannotDeriveReason::Other);
}
- }
- let bases_cannot_derive =
- info.base_members().iter().any(|base| {
- !self.ctx.whitelisted_items().contains(&base.ty.into()) ||
- self.cannot_derive_partialeq_or_partialord.contains(&base.ty.into())
- });
- if bases_cannot_derive {
- trace!(
- " base members cannot derive `PartialEq`/`PartialOrd`, so we can't \
- either"
+ let layout_can_derive = ty.layout(self.ctx).map_or(
+ CanDerive::Yes,
+ |l| {
+ l.opaque()
+ .can_trivially_derive_partialeq_or_partialord()
+ },
);
- return self.insert(id);
- }
-
- let fields_cannot_derive =
- info.fields().iter().any(|f| match *f {
- Field::DataMember(ref data) => {
- !self.ctx.whitelisted_items().contains(
- &data.ty().into(),
- ) ||
- self.cannot_derive_partialeq_or_partialord.contains(
- &data.ty().into(),
- )
+ return match layout_can_derive {
+ CanDerive::Yes => {
+ trace!(
+ " union layout can trivially derive `PartialEq`/`PartialOrd`"
+ );
+ None
}
- Field::Bitfields(ref bfu) => {
- if bfu.layout().align > RUST_DERIVE_IN_ARRAY_LIMIT {
- trace!(
- " we cannot derive PartialEq for a bitfield larger then \
- the limit"
- );
- return true;
- }
-
- bfu.bitfields().iter().any(|b| {
- !self.ctx.whitelisted_items().contains(
- &b.ty().into(),
- ) ||
- self.cannot_derive_partialeq_or_partialord.contains(
- &b.ty().into(),
- )
- })
+ CanDerive::No(reason) => {
+ trace!(
+ " union layout cannot derive `PartialEq`/`PartialOrd`"
+ );
+ Some(reason)
}
- });
- if fields_cannot_derive {
- trace!(
- " fields cannot derive `PartialEq`/`PartialOrd`, so we can't either"
- );
- return self.insert(id);
+ };
}
+ return self.constrain_join(item);
+ }
- trace!(" comp can derive PartialEq");
- ConstrainResult::Same
+ TypeKind::ResolvedTypeRef(..) |
+ TypeKind::TemplateAlias(..) |
+ TypeKind::Alias(..) |
+ TypeKind::TemplateInstantiation(..) => {
+ return self.constrain_join(item);
}
- TypeKind::TemplateInstantiation(ref template) => {
- let args_cannot_derive =
- template.template_arguments().iter().any(|arg| {
- self.cannot_derive_partialeq_or_partialord.contains(&arg.into())
- });
- if args_cannot_derive {
- trace!(
- " template args cannot derive `PartialEq`/`PartialOrd`, so \
- insantiation can't either"
- );
- return self.insert(id);
+ TypeKind::Opaque => unreachable!(
+ "The early ty.is_opaque check should have handled this case"
+ ),
+ }
+ }
+
+ fn constrain_join(&mut self, item: &Item) -> Option<CannotDeriveReason> {
+ let mut candidate = None;
+
+ item.trace(
+ self.ctx,
+ &mut |sub_id, edge_kind| {
+ // Ignore ourselves, since union with ourself is a
+ // no-op. Ignore edges that aren't relevant to the
+ // analysis.
+ if sub_id == item.id() || !Self::consider_edge(edge_kind) {
+ return;
}
- assert!(
- !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_partialeq_or_partialord.contains(
- &template.template_definition().into(),
- );
- if def_cannot_derive {
- trace!(
- " template definition cannot derive `PartialEq`/`PartialOrd`, so \
- insantiation can't either"
- );
- return self.insert(id);
+ let reason = self.cannot_derive_partialeq_or_partialord
+ .get(&sub_id)
+ .cloned();
+
+ if can_supersede(candidate, reason) {
+ candidate = reason;
}
+ },
+ &(),
+ );
- trace!(" template instantiation can derive `PartialEq`/`PartialOrd`");
- ConstrainResult::Same
- }
+ candidate
+ }
+}
- TypeKind::Opaque => {
- unreachable!(
- "The early ty.is_opaque check should have handled this case"
- )
+/// Check if the one reason could supersede another.
+///
+/// To keep this analysis monotone we should go only in one direction.
+/// If the abscence of the reason is at the bottom and `CannotDeriveReason::Other`
+/// is at the top, then we can only go upwards.
+///
+/// Other
+/// ^
+/// |
+/// ArrayTooLarge
+/// ^
+/// |
+/// None
+///
+fn can_supersede(from: Option<CannotDeriveReason>, to: Option<CannotDeriveReason>) -> bool {
+ fn rank(maybe_reason: Option<CannotDeriveReason>) -> usize {
+ match maybe_reason {
+ None => 0,
+ Some(CannotDeriveReason::ArrayTooLarge) => 1,
+ Some(CannotDeriveReason::Other) => 2,
+ }
+ }
+ rank(from) <= rank(to)
+}
+
+impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
+ type Node = ItemId;
+ type Extra = &'ctx BindgenContext;
+ type Output = HashMap<ItemId, CannotDeriveReason>;
+
+ fn new(
+ ctx: &'ctx BindgenContext,
+ ) -> CannotDerivePartialEqOrPartialOrd<'ctx> {
+ let cannot_derive_partialeq_or_partialord = HashMap::new();
+ let dependencies = generate_dependencies(ctx, Self::consider_edge);
+
+ CannotDerivePartialEqOrPartialOrd {
+ ctx,
+ cannot_derive_partialeq_or_partialord,
+ dependencies,
+ }
+ }
+
+ fn initial_worklist(&self) -> Vec<ItemId> {
+ // The transitive closure of all whitelisted items, including explicitly
+ // blacklisted items.
+ self.ctx
+ .whitelisted_items()
+ .iter()
+ .cloned()
+ .flat_map(|i| {
+ let mut reachable = vec![i];
+ i.trace(
+ self.ctx,
+ &mut |s, _| {
+ reachable.push(s);
+ },
+ &(),
+ );
+ reachable
+ })
+ .collect()
+ }
+
+ fn constrain(&mut self, id: ItemId) -> ConstrainResult {
+ trace!("constrain: {:?}", id);
+
+ if Some(CannotDeriveReason::Other)
+ == self.cannot_derive_partialeq_or_partialord.get(&id).cloned()
+ {
+ trace!(
+ " already know it cannot derive `PartialEq`/`PartialOrd`"
+ );
+ return ConstrainResult::Same;
+ }
+
+ let item = self.ctx.resolve_item(id);
+ let maybe_reason = match item.as_type() {
+ Some(ty) => {
+ self.constrain_type(item, ty).or_else(|| {
+ if ty.layout(self.ctx).map_or(false, |l| {
+ l.align > RUST_DERIVE_IN_ARRAY_LIMIT
+ })
+ {
+ // We have to be conservative: the struct *could* have enough
+ // padding that we emit an array that is longer than
+ // `RUST_DERIVE_IN_ARRAY_LIMIT`. If we moved padding calculations
+ // into the IR and computed them before this analysis, then we could
+ // be precise rather than conservative here.
+ Some(CannotDeriveReason::ArrayTooLarge)
+ } else {
+ None
+ }
+ })
}
+ None => self.constrain_join(item),
+ };
+
+ if let Some(reason) = maybe_reason {
+ self.insert(id, reason)
+ } else {
+ ConstrainResult::Same
}
}
@@ -384,7 +419,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
}
}
-impl<'ctx> From<CannotDerivePartialEqOrPartialOrd<'ctx>> for HashSet<ItemId> {
+impl<'ctx> From<CannotDerivePartialEqOrPartialOrd<'ctx>> for HashMap<ItemId, CannotDeriveReason> {
fn from(analysis: CannotDerivePartialEqOrPartialOrd<'ctx>) -> Self {
analysis.cannot_derive_partialeq_or_partialord
}
diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs
index 179fa33d..dfc96f0a 100644
--- a/src/ir/analysis/mod.rs
+++ b/src/ir/analysis/mod.rs
@@ -59,8 +59,8 @@ mod derive_partial_eq_or_partial_ord;
pub use self::derive_partial_eq_or_partial_ord::CannotDerivePartialEqOrPartialOrd;
mod has_float;
pub use self::has_float::HasFloat;
-
use ir::context::{BindgenContext, ItemId};
+
use ir::traversal::{EdgeKind, Trace};
use std::collections::HashMap;
use std::fmt;
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index c1dd369b..6a90bcbf 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -806,6 +806,27 @@ impl Base {
pub fn is_virtual(&self) -> bool {
self.kind == BaseKind::Virtual
}
+
+ /// Whether this base class should have it's own field for storage.
+ pub fn requires_storage(&self, ctx: &BindgenContext) -> bool {
+ // Virtual bases are already taken into account by the vtable
+ // pointer.
+ //
+ // FIXME(emilio): Is this always right?
+ if self.is_virtual() {
+ return false;
+ }
+
+ let base_ty = ctx.resolve_type(self.ty);
+ // NB: We won't include unsized types in our base chain because they
+ // would contribute to our size given the dummy field we insert for
+ // unsized types.
+ if base_ty.is_unsized(ctx, self.ty) {
+ return false;
+ }
+
+ true
+ }
}
/// A compound type.
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 37b71ba1..27a34162 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -7,7 +7,7 @@ use super::analysis::{CannotDeriveCopy, CannotDeriveDebug,
HasFloat, analyze};
use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault,
CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd,
- CanDerivePartialEq, CanDeriveEq};
+ CanDerivePartialEq, CanDeriveEq, CannotDeriveReason};
use super::int::IntKind;
use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet};
use super::item_kind::ItemKind;
@@ -249,7 +249,7 @@ where
{
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialord &&
- ctx.lookup_can_derive_partialeq_or_partialord(*self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none()
}
}
@@ -259,7 +259,7 @@ where
{
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialeq &&
- ctx.lookup_can_derive_partialeq_or_partialord(*self)
+ ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none()
}
}
@@ -269,7 +269,7 @@ where
{
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_eq &&
- ctx.lookup_can_derive_partialeq_or_partialord(*self) &&
+ ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() &&
!ctx.lookup_has_float(*self)
}
}
@@ -280,7 +280,7 @@ where
{
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_ord &&
- ctx.lookup_can_derive_partialeq_or_partialord(*self) &&
+ ctx.lookup_can_derive_partialeq_or_partialord(*self).is_none() &&
!ctx.lookup_has_float(*self)
}
}
@@ -423,12 +423,12 @@ pub struct BindgenContext {
/// and is always `None` before that and `Some` after.
cannot_derive_hash: Option<HashSet<ItemId>>,
- /// The set of (`ItemId`s of) types that can't derive hash.
+ /// The map why specified `ItemId`s of) types that can't derive hash.
///
/// This is populated when we enter codegen by
/// `compute_cannot_derive_partialord_partialeq_or_eq` and is always `None`
/// before that and `Some` after.
- cannot_derive_partialeq_or_partialord: Option<HashSet<ItemId>>,
+ cannot_derive_partialeq_or_partialord: Option<HashMap<ItemId, CannotDeriveReason>>,
/// The set of (`ItemId's of`) types that has vtable.
///
@@ -2365,7 +2365,7 @@ impl BindgenContext {
}
/// Look up whether the item with `id` can derive `Partial{Eq,Ord}`.
- pub fn lookup_can_derive_partialeq_or_partialord<Id: Into<ItemId>>(&self, id: Id) -> bool {
+ pub fn lookup_can_derive_partialeq_or_partialord<Id: Into<ItemId>>(&self, id: Id) -> Option<CannotDeriveReason> {
let id = id.into();
assert!(
self.in_codegen_phase(),
@@ -2374,7 +2374,7 @@ impl BindgenContext {
// Look up the computed value for whether the item with `id` can
// derive partialeq or not.
- !self.cannot_derive_partialeq_or_partialord.as_ref().unwrap().contains(&id)
+ self.cannot_derive_partialeq_or_partialord.as_ref().unwrap().get(&id).cloned()
}
/// Look up whether the item with `id` can derive `Copy` or not.
diff --git a/src/ir/derive.rs b/src/ir/derive.rs
index cafbd3b1..52e61133 100644
--- a/src/ir/derive.rs
+++ b/src/ir/derive.rs
@@ -117,5 +117,27 @@ pub trait CanTriviallyDeriveHash {
pub trait CanTriviallyDerivePartialEqOrPartialOrd {
/// Return `true` if `PartialEq` or `PartialOrd` can trivially be derived
/// for this thing, `false` otherwise.
- fn can_trivially_derive_partialeq_or_partialord(&self) -> bool;
+ fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive;
+}
+
+/// Reason why exactly we cannot automatically derive a trait.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum CannotDeriveReason {
+ /// The only thing that stops us from automatically deriving is that
+ /// array with more than maximum number of elements is used.
+ ///
+ /// This means we probably can "manually" implement such trait.
+ ArrayTooLarge,
+
+ /// Any other reason.
+ Other,
+}
+
+/// Whether it is possible or not to derive trait automatically.
+pub enum CanDerive {
+ /// Yes, we can!
+ Yes,
+
+ /// No, we cannot. Contains reason why exactly we can't derive.
+ No(CannotDeriveReason)
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index ccdfc4f3..3a9f337c 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -9,7 +9,7 @@ use super::ty::TypeKind;
use clang;
use clang_sys::{self, CXCallingConv};
use ir::derive::{CanTriviallyDeriveDebug, CanTriviallyDeriveHash,
- CanTriviallyDerivePartialEqOrPartialOrd};
+ CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason};
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};
use quote;
use std::io;
@@ -560,7 +560,14 @@ impl CanTriviallyDeriveHash for FunctionSig {
}
impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig {
- fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
- self.function_pointers_can_derive()
+ fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive {
+ if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
+ return CanDerive::No(CannotDeriveReason::Other);
+ }
+
+ match self.abi {
+ Abi::C | Abi::Unknown(..) => CanDerive::Yes,
+ _ => CanDerive::No(CannotDeriveReason::Other),
+ }
}
}
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 010528b6..dbc352eb 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -347,21 +347,21 @@ impl CanDeriveHash for Item {
impl CanDerivePartialOrd for Item {
fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialord &&
- ctx.lookup_can_derive_partialeq_or_partialord(self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none()
}
}
impl CanDerivePartialEq for Item {
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_partialeq &&
- ctx.lookup_can_derive_partialeq_or_partialord(self.id())
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none()
}
}
impl CanDeriveEq for Item {
fn can_derive_eq(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_eq &&
- ctx.lookup_can_derive_partialeq_or_partialord(self.id()) &&
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() &&
!ctx.lookup_has_float(self.id())
}
}
@@ -369,7 +369,7 @@ impl CanDeriveEq for Item {
impl CanDeriveOrd for Item {
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool {
ctx.options().derive_ord &&
- ctx.lookup_can_derive_partialeq_or_partialord(self.id()) &&
+ ctx.lookup_can_derive_partialeq_or_partialord(self.id()).is_none() &&
!ctx.lookup_has_float(self.id())
}
}
diff --git a/src/ir/layout.rs b/src/ir/layout.rs
index 2df15ef2..0d9c123f 100644
--- a/src/ir/layout.rs
+++ b/src/ir/layout.rs
@@ -2,7 +2,7 @@
use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
- CanTriviallyDerivePartialEqOrPartialOrd};
+ CanTriviallyDerivePartialEqOrPartialOrd, CanDerive, CannotDeriveReason};
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
use clang;
use std::{cmp, mem};
@@ -140,7 +140,13 @@ impl CanTriviallyDeriveHash for Opaque {
}
impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
- fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
- self.array_size_within_derive_limit()
+ fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive {
+ self.array_size().map_or(CanDerive::No(CannotDeriveReason::Other), |size| {
+ if size <= RUST_DERIVE_IN_ARRAY_LIMIT {
+ CanDerive::Yes
+ } else {
+ CanDerive::No(CannotDeriveReason::ArrayTooLarge)
+ }
+ })
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 9e54ddc9..b540653e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -239,6 +239,14 @@ impl Builder {
output_vector.push("--no-layout-tests".into());
}
+ if self.options.impl_debug {
+ output_vector.push("--impl-debug".into());
+ }
+
+ if self.options.impl_partialeq {
+ output_vector.push("--impl-partialeq".into());
+ }
+
if !self.options.derive_copy {
output_vector.push("--no-derive-copy".into());
}
@@ -247,10 +255,6 @@ impl Builder {
output_vector.push("--no-derive-debug".into());
}
- if self.options.impl_debug {
- output_vector.push("--impl-debug".into());
- }
-
if !self.options.derive_default {
output_vector.push("--no-derive-default".into());
} else {
@@ -806,6 +810,18 @@ impl Builder {
self
}
+ /// Set whether `Debug` should be implemented, if it can not be derived automatically.
+ pub fn impl_debug(mut self, doit: bool) -> Self {
+ self.options.impl_debug = doit;
+ self
+ }
+
+ /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
+ pub fn impl_partialeq(mut self, doit: bool) -> Self {
+ self.options.impl_partialeq = doit;
+ self
+ }
+
/// Set whether `Copy` should be derived by default.
pub fn derive_copy(mut self, doit: bool) -> Self {
self.options.derive_copy = doit;
@@ -818,12 +834,6 @@ impl Builder {
self
}
- /// Set whether `Debug` should be implemented, if it can not be derived automatically.
- pub fn impl_debug(mut self, doit: bool) -> Self {
- self.options.impl_debug = doit;
- self
- }
-
/// Set whether `Default` should be derived by default.
pub fn derive_default(mut self, doit: bool) -> Self {
self.options.derive_default = doit;
@@ -1209,6 +1219,14 @@ struct BindgenOptions {
/// True if we should generate layout tests for generated structures.
layout_tests: bool,
+ /// True if we should implement the Debug trait for C/C++ structures and types
+ /// that do not support automatically deriving Debug.
+ impl_debug: bool,
+
+ /// True if we should implement the PartialEq trait for C/C++ structures and types
+ /// that do not support autoamically deriving PartialEq.
+ impl_partialeq: bool,
+
/// True if we should derive Copy trait implementations for C/C++ structures
/// and types.
derive_copy: bool,
@@ -1217,10 +1235,6 @@ struct BindgenOptions {
/// and types.
derive_debug: bool,
- /// True if we should implement the Debug trait for C/C++ structures and types
- /// that do not support automatically deriving Debug.
- impl_debug: bool,
-
/// True if we should derive Default trait implementations for C/C++ structures
/// and types.
derive_default: bool,
@@ -1386,9 +1400,10 @@ impl Default for BindgenOptions {
emit_ir: false,
emit_ir_graphviz: None,
layout_tests: true,
+ impl_debug: false,
+ impl_partialeq: false,
derive_copy: true,
derive_debug: true,
- impl_debug: false,
derive_default: false,
derive_hash: false,
derive_partialord: false,
diff --git a/src/options.rs b/src/options.rs
index aec4a2bd..64ee249e 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -66,14 +66,18 @@ where
Arg::with_name("no-derive-debug")
.long("no-derive-debug")
.help("Avoid deriving Debug on any type."),
- Arg::with_name("impl-debug")
- .long("impl-debug")
- .help("Create Debug implementation, if it can not be derived \
- automatically."),
Arg::with_name("no-derive-default")
.long("no-derive-default")
.hidden(true)
.help("Avoid deriving Default on any type."),
+ Arg::with_name("impl-debug")
+ .long("impl-debug")
+ .help("Create Debug implementation, if it can not be derived \
+ automatically."),
+ Arg::with_name("impl-partialeq")
+ .long("impl-partialeq")
+ .help("Create PartialEq implementation, if it can not be derived \
+ automatically."),
Arg::with_name("with-derive-default")
.long("with-derive-default")
.help("Derive Default on any type."),
@@ -347,6 +351,10 @@ where
builder = builder.impl_debug(true);
}
+ if matches.is_present("impl-partialeq") {
+ builder = builder.impl_partialeq(true);
+ }
+
if matches.is_present("with-derive-default") {
builder = builder.derive_default(true);
}
diff --git a/tests/expectations/tests/class_1_0.rs b/tests/expectations/tests/class_1_0.rs
index 8ccf4e01..669b7364 100644
--- a/tests/expectations/tests/class_1_0.rs
+++ b/tests/expectations/tests/class_1_0.rs
@@ -7,13 +7,15 @@
#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
-impl <T> __IncompleteArrayField<T> {
+impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData)
}
#[inline]
- pub unsafe fn as_ptr(&self) -> *const T { ::std::mem::transmute(self) }
+ pub unsafe fn as_ptr(&self) -> *const T {
+ ::std::mem::transmute(self)
+ }
#[inline]
pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
::std::mem::transmute(self)
@@ -27,47 +29,61 @@ impl <T> __IncompleteArrayField<T> {
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
-impl <T> ::std::fmt::Debug for __IncompleteArrayField<T> {
+impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
}
-impl <T> ::std::clone::Clone for __IncompleteArrayField<T> {
+impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
#[inline]
- fn clone(&self) -> Self { Self::new() }
+ fn clone(&self) -> Self {
+ Self::new()
+ }
}
-impl <T> ::std::marker::Copy for __IncompleteArrayField<T> { }
+impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
#[repr(C)]
pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
-impl <T> __BindgenUnionField<T> {
+impl<T> __BindgenUnionField<T> {
#[inline]
- pub fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) }
+ pub fn new() -> Self {
+ __BindgenUnionField(::std::marker::PhantomData)
+ }
#[inline]
- pub unsafe fn as_ref(&self) -> &T { ::std::mem::transmute(self) }
+ pub unsafe fn as_ref(&self) -> &T {
+ ::std::mem::transmute(self)
+ }
#[inline]
- pub unsafe fn as_mut(&mut self) -> &mut T { ::std::mem::transmute(self) }
+ pub unsafe fn as_mut(&mut self) -> &mut T {
+ ::std::mem::transmute(self)
+ }
}
-impl <T> ::std::default::Default for __BindgenUnionField<T> {
+impl<T> ::std::default::Default for __BindgenUnionField<T> {
#[inline]
- fn default() -> Self { Self::new() }
+ fn default() -> Self {
+ Self::new()
+ }
}
-impl <T> ::std::clone::Clone for __BindgenUnionField<T> {
+impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
#[inline]
- fn clone(&self) -> Self { Self::new() }
+ fn clone(&self) -> Self {
+ Self::new()
+ }
}
-impl <T> ::std::marker::Copy for __BindgenUnionField<T> { }
-impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
+impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
+impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fmt.write_str("__BindgenUnionField")
}
}
-impl <T> ::std::hash::Hash for __BindgenUnionField<T> {
- fn hash<H: ::std::hash::Hasher>(&self, _state: &mut H) { }
+impl<T> ::std::hash::Hash for __BindgenUnionField<T> {
+ fn hash<H: ::std::hash::Hasher>(&self, _state: &mut H) {}
}
-impl <T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
- fn eq(&self, _other: &__BindgenUnionField<T>) -> bool { true }
+impl<T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
+ fn eq(&self, _other: &__BindgenUnionField<T>) -> bool {
+ true
+ }
}
-impl <T> ::std::cmp::Eq for __BindgenUnionField<T> { }
+impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
#[repr(C)]
#[derive(Copy)]
pub struct C {
@@ -76,25 +92,46 @@ pub struct C {
}
#[test]
fn bindgen_test_layout_C() {
- assert_eq!(::std::mem::size_of::<C>() , 40usize , concat ! (
- "Size of: " , stringify ! ( C ) ));
- assert_eq! (::std::mem::align_of::<C>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( C ) ));
- assert_eq! (unsafe { & ( * ( 0 as * const C ) ) . a as * const _ as usize
- } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( C ) , "::" , stringify
- ! ( a ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const C ) ) . big_array as * const _ as usize }
- , 4usize , concat ! (
- "Alignment of field: " , stringify ! ( C ) , "::" , stringify
- ! ( big_array ) ));
+ assert_eq!(
+ ::std::mem::size_of::<C>(),
+ 40usize,
+ concat!("Size of: ", stringify!(C))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<C>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(C))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C)).a as *const _ as usize },
+ 0usize,
+ concat!("Alignment of field: ", stringify!(C), "::", stringify!(a))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C)).big_array as *const _ as usize },
+ 4usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C),
+ "::",
+ stringify!(big_array)
+ )
+ );
}
impl Clone for C {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for C {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for C {
+ fn eq(&self, other: &C) -> bool {
+ self.a == other.a && &self.big_array[..] == &other.big_array[..]
+ }
}
#[repr(C)]
pub struct C_with_zero_length_array {
@@ -104,33 +141,53 @@ pub struct C_with_zero_length_array {
}
#[test]
fn bindgen_test_layout_C_with_zero_length_array() {
- assert_eq!(::std::mem::size_of::<C_with_zero_length_array>() , 40usize ,
- concat ! (
- "Size of: " , stringify ! ( C_with_zero_length_array ) ));
- assert_eq! (::std::mem::align_of::<C_with_zero_length_array>() , 4usize ,
- concat ! (
- "Alignment of " , stringify ! ( C_with_zero_length_array ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const C_with_zero_length_array ) ) . a as *
- const _ as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! (
- C_with_zero_length_array ) , "::" , stringify ! ( a ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const C_with_zero_length_array ) ) . big_array
- as * const _ as usize } , 4usize , concat ! (
- "Alignment of field: " , stringify ! (
- C_with_zero_length_array ) , "::" , stringify ! ( big_array )
- ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const C_with_zero_length_array ) ) .
- zero_length_array as * const _ as usize } , 37usize , concat !
- (
- "Alignment of field: " , stringify ! (
- C_with_zero_length_array ) , "::" , stringify ! (
- zero_length_array ) ));
+ assert_eq!(
+ ::std::mem::size_of::<C_with_zero_length_array>(),
+ 40usize,
+ concat!("Size of: ", stringify!(C_with_zero_length_array))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<C_with_zero_length_array>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(C_with_zero_length_array))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C_with_zero_length_array)).a as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C_with_zero_length_array),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C_with_zero_length_array)).big_array as *const _ as usize },
+ 4usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C_with_zero_length_array),
+ "::",
+ stringify!(big_array)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(0 as *const C_with_zero_length_array)).zero_length_array as *const _ as usize
+ },
+ 37usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C_with_zero_length_array),
+ "::",
+ stringify!(zero_length_array)
+ )
+ );
}
impl Default for C_with_zero_length_array {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[repr(C)]
pub struct C_with_incomplete_array {
@@ -140,15 +197,21 @@ pub struct C_with_incomplete_array {
}
#[test]
fn bindgen_test_layout_C_with_incomplete_array() {
- assert_eq!(::std::mem::size_of::<C_with_incomplete_array>() , 40usize ,
- concat ! (
- "Size of: " , stringify ! ( C_with_incomplete_array ) ));
- assert_eq! (::std::mem::align_of::<C_with_incomplete_array>() , 4usize ,
- concat ! (
- "Alignment of " , stringify ! ( C_with_incomplete_array ) ));
+ assert_eq!(
+ ::std::mem::size_of::<C_with_incomplete_array>(),
+ 40usize,
+ concat!("Size of: ", stringify!(C_with_incomplete_array))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<C_with_incomplete_array>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(C_with_incomplete_array))
+ );
}
impl Default for C_with_incomplete_array {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[repr(C)]
pub struct C_with_zero_length_array_and_incomplete_array {
@@ -159,17 +222,27 @@ pub struct C_with_zero_length_array_and_incomplete_array {
}
#[test]
fn bindgen_test_layout_C_with_zero_length_array_and_incomplete_array() {
- assert_eq!(::std::mem::size_of::<C_with_zero_length_array_and_incomplete_array>()
- , 40usize , concat ! (
- "Size of: " , stringify ! (
- C_with_zero_length_array_and_incomplete_array ) ));
- assert_eq! (::std::mem::align_of::<C_with_zero_length_array_and_incomplete_array>()
- , 4usize , concat ! (
- "Alignment of " , stringify ! (
- C_with_zero_length_array_and_incomplete_array ) ));
+ assert_eq!(
+ ::std::mem::size_of::<C_with_zero_length_array_and_incomplete_array>(),
+ 40usize,
+ concat!(
+ "Size of: ",
+ stringify!(C_with_zero_length_array_and_incomplete_array)
+ )
+ );
+ assert_eq!(
+ ::std::mem::align_of::<C_with_zero_length_array_and_incomplete_array>(),
+ 4usize,
+ concat!(
+ "Alignment of ",
+ stringify!(C_with_zero_length_array_and_incomplete_array)
+ )
+ );
}
impl Default for C_with_zero_length_array_and_incomplete_array {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[repr(C)]
#[derive(Debug, Default, Hash, PartialEq, Eq)]
@@ -178,15 +251,26 @@ pub struct WithDtor {
}
#[test]
fn bindgen_test_layout_WithDtor() {
- assert_eq!(::std::mem::size_of::<WithDtor>() , 4usize , concat ! (
- "Size of: " , stringify ! ( WithDtor ) ));
- assert_eq! (::std::mem::align_of::<WithDtor>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( WithDtor ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const WithDtor ) ) . b as * const _ as usize }
- , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( WithDtor ) , "::" ,
- stringify ! ( b ) ));
+ assert_eq!(
+ ::std::mem::size_of::<WithDtor>(),
+ 4usize,
+ concat!("Size of: ", stringify!(WithDtor))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<WithDtor>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(WithDtor))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const WithDtor)).b as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(WithDtor),
+ "::",
+ stringify!(b)
+ )
+ );
}
#[repr(C)]
pub struct IncompleteArrayNonCopiable {
@@ -195,16 +279,21 @@ pub struct IncompleteArrayNonCopiable {
}
#[test]
fn bindgen_test_layout_IncompleteArrayNonCopiable() {
- assert_eq!(::std::mem::size_of::<IncompleteArrayNonCopiable>() , 8usize ,
- concat ! (
- "Size of: " , stringify ! ( IncompleteArrayNonCopiable ) ));
- assert_eq! (::std::mem::align_of::<IncompleteArrayNonCopiable>() , 8usize
- , concat ! (
- "Alignment of " , stringify ! ( IncompleteArrayNonCopiable )
- ));
+ assert_eq!(
+ ::std::mem::size_of::<IncompleteArrayNonCopiable>(),
+ 8usize,
+ concat!("Size of: ", stringify!(IncompleteArrayNonCopiable))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<IncompleteArrayNonCopiable>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(IncompleteArrayNonCopiable))
+ );
}
impl Default for IncompleteArrayNonCopiable {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Hash, PartialEq)]
@@ -215,23 +304,41 @@ pub struct Union {
}
#[test]
fn bindgen_test_layout_Union() {
- assert_eq!(::std::mem::size_of::<Union>() , 4usize , concat ! (
- "Size of: " , stringify ! ( Union ) ));
- assert_eq! (::std::mem::align_of::<Union>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( Union ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const Union ) ) . d as * const _ as usize } ,
- 0usize , concat ! (
- "Alignment of field: " , stringify ! ( Union ) , "::" ,
- stringify ! ( d ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const Union ) ) . i as * const _ as usize } ,
- 0usize , concat ! (
- "Alignment of field: " , stringify ! ( Union ) , "::" ,
- stringify ! ( i ) ));
+ assert_eq!(
+ ::std::mem::size_of::<Union>(),
+ 4usize,
+ concat!("Size of: ", stringify!(Union))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Union>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Union))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const Union)).d as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(Union),
+ "::",
+ stringify!(d)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const Union)).i as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(Union),
+ "::",
+ stringify!(i)
+ )
+ );
}
impl Clone for Union {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Hash, PartialEq)]
@@ -240,18 +347,31 @@ pub struct WithUnion {
}
#[test]
fn bindgen_test_layout_WithUnion() {
- assert_eq!(::std::mem::size_of::<WithUnion>() , 4usize , concat ! (
- "Size of: " , stringify ! ( WithUnion ) ));
- assert_eq! (::std::mem::align_of::<WithUnion>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( WithUnion ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const WithUnion ) ) . data as * const _ as
- usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( WithUnion ) , "::" ,
- stringify ! ( data ) ));
+ assert_eq!(
+ ::std::mem::size_of::<WithUnion>(),
+ 4usize,
+ concat!("Size of: ", stringify!(WithUnion))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<WithUnion>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(WithUnion))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const WithUnion)).data as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(WithUnion),
+ "::",
+ stringify!(data)
+ )
+ );
}
impl Clone for WithUnion {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)]
@@ -260,41 +380,49 @@ pub struct RealAbstractionWithTonsOfMethods {
}
#[test]
fn bindgen_test_layout_RealAbstractionWithTonsOfMethods() {
- assert_eq!(::std::mem::size_of::<RealAbstractionWithTonsOfMethods>() ,
- 1usize , concat ! (
- "Size of: " , stringify ! ( RealAbstractionWithTonsOfMethods )
- ));
- assert_eq! (::std::mem::align_of::<RealAbstractionWithTonsOfMethods>() ,
- 1usize , concat ! (
- "Alignment of " , stringify ! (
- RealAbstractionWithTonsOfMethods ) ));
+ assert_eq!(
+ ::std::mem::size_of::<RealAbstractionWithTonsOfMethods>(),
+ 1usize,
+ concat!("Size of: ", stringify!(RealAbstractionWithTonsOfMethods))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<RealAbstractionWithTonsOfMethods>(),
+ 1usize,
+ concat!(
+ "Alignment of ",
+ stringify!(RealAbstractionWithTonsOfMethods)
+ )
+ );
}
extern "C" {
#[link_name = "_ZNK32RealAbstractionWithTonsOfMethods3barEv"]
- pub fn RealAbstractionWithTonsOfMethods_bar(this:
- *const RealAbstractionWithTonsOfMethods);
+ pub fn RealAbstractionWithTonsOfMethods_bar(this: *const RealAbstractionWithTonsOfMethods);
}
extern "C" {
#[link_name = "_ZN32RealAbstractionWithTonsOfMethods3barEv"]
- pub fn RealAbstractionWithTonsOfMethods_bar1(this:
- *mut RealAbstractionWithTonsOfMethods);
+ pub fn RealAbstractionWithTonsOfMethods_bar1(this: *mut RealAbstractionWithTonsOfMethods);
}
extern "C" {
#[link_name = "_ZN32RealAbstractionWithTonsOfMethods3barEi"]
- pub fn RealAbstractionWithTonsOfMethods_bar2(this:
- *mut RealAbstractionWithTonsOfMethods,
- foo: ::std::os::raw::c_int);
+ pub fn RealAbstractionWithTonsOfMethods_bar2(
+ this: *mut RealAbstractionWithTonsOfMethods,
+ foo: ::std::os::raw::c_int,
+ );
}
extern "C" {
#[link_name = "_ZN32RealAbstractionWithTonsOfMethods3staEv"]
pub fn RealAbstractionWithTonsOfMethods_sta();
}
impl Clone for RealAbstractionWithTonsOfMethods {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl RealAbstractionWithTonsOfMethods {
#[inline]
- pub unsafe fn bar(&self) { RealAbstractionWithTonsOfMethods_bar(self) }
+ pub unsafe fn bar(&self) {
+ RealAbstractionWithTonsOfMethods_bar(self)
+ }
#[inline]
pub unsafe fn bar1(&mut self) {
RealAbstractionWithTonsOfMethods_bar1(self)
@@ -304,5 +432,7 @@ impl RealAbstractionWithTonsOfMethods {
RealAbstractionWithTonsOfMethods_bar2(self, foo)
}
#[inline]
- pub unsafe fn sta() { RealAbstractionWithTonsOfMethods_sta() }
+ pub unsafe fn sta() {
+ RealAbstractionWithTonsOfMethods_sta()
+ }
}
diff --git a/tests/expectations/tests/derive-partialeq-anonfield.rs b/tests/expectations/tests/derive-partialeq-anonfield.rs
new file mode 100644
index 00000000..6e3446d5
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-anonfield.rs
@@ -0,0 +1,57 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct rte_mbuf {
+ pub __bindgen_anon_1: rte_mbuf__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Copy)]
+pub union rte_mbuf__bindgen_ty_1 {
+ _bindgen_union_align: [u8; 0usize],
+}
+#[test]
+fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() {
+ assert_eq!(
+ ::std::mem::size_of::<rte_mbuf__bindgen_ty_1>(),
+ 0usize,
+ concat!("Size of: ", stringify!(rte_mbuf__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<rte_mbuf__bindgen_ty_1>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(rte_mbuf__bindgen_ty_1))
+ );
+}
+impl Clone for rte_mbuf__bindgen_ty_1 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for rte_mbuf__bindgen_ty_1 {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+#[test]
+fn bindgen_test_layout_rte_mbuf() {
+ assert_eq!(
+ ::std::mem::size_of::<rte_mbuf>(),
+ 0usize,
+ concat!("Size of: ", stringify!(rte_mbuf))
+ );
+}
+impl Clone for rte_mbuf {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for rte_mbuf {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-base.rs b/tests/expectations/tests/derive-partialeq-base.rs
new file mode 100644
index 00000000..12356655
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-base.rs
@@ -0,0 +1,82 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct Base {
+ pub large: [::std::os::raw::c_int; 33usize],
+}
+#[test]
+fn bindgen_test_layout_Base() {
+ assert_eq!(
+ ::std::mem::size_of::<Base>(),
+ 132usize,
+ concat!("Size of: ", stringify!(Base))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Base>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(Base))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const Base)).large as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(Base),
+ "::",
+ stringify!(large)
+ )
+ );
+}
+impl Clone for Base {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for Base {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for Base {
+ fn eq(&self, other: &Base) -> bool {
+ &self.large[..] == &other.large[..]
+ }
+}
+#[repr(C)]
+#[derive(Copy)]
+pub struct ShouldDerivePartialEq {
+ pub _base: Base,
+}
+#[test]
+fn bindgen_test_layout_ShouldDerivePartialEq() {
+ assert_eq!(
+ ::std::mem::size_of::<ShouldDerivePartialEq>(),
+ 132usize,
+ concat!("Size of: ", stringify!(ShouldDerivePartialEq))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ShouldDerivePartialEq>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(ShouldDerivePartialEq))
+ );
+}
+impl Clone for ShouldDerivePartialEq {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for ShouldDerivePartialEq {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for ShouldDerivePartialEq {
+ fn eq(&self, other: &ShouldDerivePartialEq) -> bool {
+ self._base == other._base
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-bitfield.rs b/tests/expectations/tests/derive-partialeq-bitfield.rs
new file mode 100644
index 00000000..b788f6c3
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-bitfield.rs
@@ -0,0 +1,130 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct C {
+ pub _bitfield_1: u8,
+ pub large_array: [::std::os::raw::c_int; 50usize],
+}
+#[test]
+fn bindgen_test_layout_C() {
+ assert_eq!(
+ ::std::mem::size_of::<C>(),
+ 204usize,
+ concat!("Size of: ", stringify!(C))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<C>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(C))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C)).large_array as *const _ as usize },
+ 4usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C),
+ "::",
+ stringify!(large_array)
+ )
+ );
+}
+impl Clone for C {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for C {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for C {
+ fn eq(&self, other: &C) -> bool {
+ self.a() == other.a() && self.b() == other.b() &&
+ &self.large_array[..] == &other.large_array[..]
+ }
+}
+impl C {
+ #[inline]
+ pub fn a(&self) -> bool {
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ let mask = 1u64 as u8;
+ let val = (unit_field_val & mask) >> 0usize;
+ unsafe { ::std::mem::transmute(val as u8) }
+ }
+ #[inline]
+ pub fn set_a(&mut self, val: bool) {
+ let mask = 1u64 as u8;
+ let val = val as u8 as u8;
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 0usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &unit_field_val as *const _ as *const u8,
+ &mut self._bitfield_1 as *mut _ as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ );
+ }
+ }
+ #[inline]
+ pub fn b(&self) -> bool {
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ let mask = 254u64 as u8;
+ let val = (unit_field_val & mask) >> 1usize;
+ unsafe { ::std::mem::transmute(val as u8) }
+ }
+ #[inline]
+ pub fn set_b(&mut self, val: bool) {
+ let mask = 254u64 as u8;
+ let val = val as u8 as u8;
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 1usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &unit_field_val as *const _ as *const u8,
+ &mut self._bitfield_1 as *mut _ as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ );
+ }
+ }
+ #[inline]
+ pub fn new_bitfield_1(a: bool, b: bool) -> u8 {
+ ((0 | ((a as u8 as u8) << 0usize) & (1u64 as u8)) |
+ ((b as u8 as u8) << 1usize) & (254u64 as u8))
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-core.rs b/tests/expectations/tests/derive-partialeq-core.rs
new file mode 100644
index 00000000..1660f178
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-core.rs
@@ -0,0 +1,50 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+extern crate core;
+
+#[repr(C)]
+#[derive(Copy)]
+pub struct C {
+ pub large_array: [::std::os::raw::c_int; 420usize],
+}
+#[test]
+fn bindgen_test_layout_C() {
+ assert_eq!(
+ ::core::mem::size_of::<C>(),
+ 1680usize,
+ concat!("Size of: ", stringify!(C))
+ );
+ assert_eq!(
+ ::core::mem::align_of::<C>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(C))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const C)).large_array as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(C),
+ "::",
+ stringify!(large_array)
+ )
+ );
+}
+impl Clone for C {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for C {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+}
+impl ::core::cmp::PartialEq for C {
+ fn eq(&self, other: &C) -> bool {
+ &self.large_array[..] == &other.large_array[..]
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-pointer.rs b/tests/expectations/tests/derive-partialeq-pointer.rs
new file mode 100644
index 00000000..b1d3f04c
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-pointer.rs
@@ -0,0 +1,129 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Debug, Copy, Hash, PartialEq, Eq)]
+pub struct Bar {
+ pub b: *mut a,
+}
+#[test]
+fn bindgen_test_layout_Bar() {
+ assert_eq!(
+ ::std::mem::size_of::<Bar>(),
+ 8usize,
+ concat!("Size of: ", stringify!(Bar))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Bar>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(Bar))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const Bar)).b as *const _ as usize },
+ 0usize,
+ concat!("Alignment of field: ", stringify!(Bar), "::", stringify!(b))
+ );
+}
+impl Clone for Bar {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for Bar {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+#[repr(C)]
+#[derive(Copy)]
+pub struct c {
+ pub __bindgen_anon_1: c__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Copy)]
+pub union c__bindgen_ty_1 {
+ _bindgen_union_align: u8,
+ pub _address: u8,
+}
+#[test]
+fn bindgen_test_layout_c__bindgen_ty_1() {
+ assert_eq!(
+ ::std::mem::size_of::<c__bindgen_ty_1>(),
+ 1usize,
+ concat!("Size of: ", stringify!(c__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<c__bindgen_ty_1>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(c__bindgen_ty_1))
+ );
+}
+impl Clone for c__bindgen_ty_1 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for c__bindgen_ty_1 {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+#[test]
+fn bindgen_test_layout_c() {
+ assert_eq!(
+ ::std::mem::size_of::<c>(),
+ 1usize,
+ concat!("Size of: ", stringify!(c))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<c>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(c))
+ );
+}
+impl Clone for c {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for c {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+#[repr(C)]
+#[derive(Copy)]
+pub struct a {
+ pub d: c,
+}
+#[test]
+fn bindgen_test_layout_a() {
+ assert_eq!(
+ ::std::mem::size_of::<a>(),
+ 1usize,
+ concat!("Size of: ", stringify!(a))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<a>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(a))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const a)).d as *const _ as usize },
+ 0usize,
+ concat!("Alignment of field: ", stringify!(a), "::", stringify!(d))
+ );
+}
+impl Clone for a {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for a {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-union.rs b/tests/expectations/tests/derive-partialeq-union.rs
new file mode 100644
index 00000000..dfb5a5ae
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-union.rs
@@ -0,0 +1,56 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub union ShouldNotDerivePartialEq {
+ pub a: ::std::os::raw::c_char,
+ pub b: ::std::os::raw::c_int,
+ _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotDerivePartialEq() {
+ assert_eq!(
+ ::std::mem::size_of::<ShouldNotDerivePartialEq>(),
+ 4usize,
+ concat!("Size of: ", stringify!(ShouldNotDerivePartialEq))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ShouldNotDerivePartialEq>(),
+ 4usize,
+ 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)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ShouldNotDerivePartialEq)).b as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ShouldNotDerivePartialEq),
+ "::",
+ stringify!(b)
+ )
+ );
+}
+impl Clone for ShouldNotDerivePartialEq {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for ShouldNotDerivePartialEq {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
diff --git a/tests/expectations/tests/derive-partialeq-union_1_0.rs b/tests/expectations/tests/derive-partialeq-union_1_0.rs
new file mode 100644
index 00000000..f5d30f03
--- /dev/null
+++ b/tests/expectations/tests/derive-partialeq-union_1_0.rs
@@ -0,0 +1,104 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
+impl<T> __BindgenUnionField<T> {
+ #[inline]
+ pub fn new() -> Self {
+ __BindgenUnionField(::std::marker::PhantomData)
+ }
+ #[inline]
+ pub unsafe fn as_ref(&self) -> &T {
+ ::std::mem::transmute(self)
+ }
+ #[inline]
+ pub unsafe fn as_mut(&mut self) -> &mut T {
+ ::std::mem::transmute(self)
+ }
+}
+impl<T> ::std::default::Default for __BindgenUnionField<T> {
+ #[inline]
+ fn default() -> Self {
+ Self::new()
+ }
+}
+impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self::new()
+ }
+}
+impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
+impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
+ fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fmt.write_str("__BindgenUnionField")
+ }
+}
+impl<T> ::std::hash::Hash for __BindgenUnionField<T> {
+ fn hash<H: ::std::hash::Hasher>(&self, _state: &mut H) {}
+}
+impl<T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
+ fn eq(&self, _other: &__BindgenUnionField<T>) -> bool {
+ true
+ }
+}
+impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
+#[repr(C)]
+#[derive(Copy)]
+pub struct ShouldDerivePartialEq {
+ pub a: __BindgenUnionField<[::std::os::raw::c_char; 150usize]>,
+ pub b: __BindgenUnionField<::std::os::raw::c_int>,
+ pub bindgen_union_field: [u32; 38usize],
+}
+#[test]
+fn bindgen_test_layout_ShouldDerivePartialEq() {
+ assert_eq!(
+ ::std::mem::size_of::<ShouldDerivePartialEq>(),
+ 152usize,
+ concat!("Size of: ", stringify!(ShouldDerivePartialEq))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ShouldDerivePartialEq>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(ShouldDerivePartialEq))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ShouldDerivePartialEq)).a as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ShouldDerivePartialEq),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ShouldDerivePartialEq)).b as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ShouldDerivePartialEq),
+ "::",
+ stringify!(b)
+ )
+ );
+}
+impl Clone for ShouldDerivePartialEq {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for ShouldDerivePartialEq {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for ShouldDerivePartialEq {
+ fn eq(&self, other: &ShouldDerivePartialEq) -> bool {
+ &self.bindgen_union_field[..] == &other.bindgen_union_field[..]
+ }
+}
diff --git a/tests/expectations/tests/issue-648-derive-debug-with-padding.rs b/tests/expectations/tests/issue-648-derive-debug-with-padding.rs
index 27b5cfcd..11c318a2 100644
--- a/tests/expectations/tests/issue-648-derive-debug-with-padding.rs
+++ b/tests/expectations/tests/issue-648-derive-debug-with-padding.rs
@@ -43,6 +43,11 @@ impl Default for NoDebug {
unsafe { ::std::mem::zeroed() }
}
}
+impl ::std::cmp::PartialEq for NoDebug {
+ fn eq(&self, other: &NoDebug) -> bool {
+ self.c == other.c
+ }
+}
/// This should derive Debug/Hash/PartialEq/Eq because the padding size is less than the max derive
/// Debug/Hash/PartialEq/Eq impl for arrays. However, we conservatively don't derive Debug/Hash because
/// we determine Debug derive-ability before we compute padding, which happens at
@@ -92,3 +97,8 @@ impl Default for ShouldDeriveDebugButDoesNot {
unsafe { ::std::mem::zeroed() }
}
}
+impl ::std::cmp::PartialEq for ShouldDeriveDebugButDoesNot {
+ fn eq(&self, other: &ShouldDeriveDebugButDoesNot) -> bool {
+ self.c == other.c && self.d == other.d
+ }
+}
diff --git a/tests/expectations/tests/layout_array.rs b/tests/expectations/tests/layout_array.rs
index 9f2082ec..c1a15187 100644
--- a/tests/expectations/tests/layout_array.rs
+++ b/tests/expectations/tests/layout_array.rs
@@ -21,30 +21,32 @@ pub struct rte_mempool {
/// it will most likely point to a different type of data structure, and
/// will be transparent to the application programmer.
/// This function should set mp->pool_data.
-pub type rte_mempool_alloc_t =
- ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool)
- -> ::std::os::raw::c_int>;
+pub type rte_mempool_alloc_t = ::std::option::Option<
+ unsafe extern "C" fn(mp: *mut rte_mempool) -> ::std::os::raw::c_int,
+>;
/// Free the opaque private data pointed to by mp->pool_data pointer.
-pub type rte_mempool_free_t =
- ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool)>;
+pub type rte_mempool_free_t = ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool)>;
/// Enqueue an object into the external pool.
-pub type rte_mempool_enqueue_t =
- ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool,
- obj_table:
- *const *const ::std::os::raw::c_void,
- n: ::std::os::raw::c_uint)
- -> ::std::os::raw::c_int>;
+pub type rte_mempool_enqueue_t = ::std::option::Option<
+ unsafe extern "C" fn(
+ mp: *mut rte_mempool,
+ obj_table: *const *const ::std::os::raw::c_void,
+ n: ::std::os::raw::c_uint,
+ ) -> ::std::os::raw::c_int,
+>;
/// Dequeue an object from the external pool.
-pub type rte_mempool_dequeue_t =
- ::std::option::Option<unsafe extern "C" fn(mp: *mut rte_mempool,
- obj_table:
- *mut *mut ::std::os::raw::c_void,
- n: ::std::os::raw::c_uint)
- -> ::std::os::raw::c_int>;
+pub type rte_mempool_dequeue_t = ::std::option::Option<
+ unsafe extern "C" fn(
+ mp: *mut rte_mempool,
+ obj_table: *mut *mut ::std::os::raw::c_void,
+ n: ::std::os::raw::c_uint,
+ ) -> ::std::os::raw::c_int,
+>;
/// Return the number of available objects in the external pool.
-pub type rte_mempool_get_count =
- ::std::option::Option<unsafe extern "C" fn(mp: *const rte_mempool)
- -> ::std::os::raw::c_uint>;
+pub type rte_mempool_get_count = ::std::option::Option<
+ unsafe extern "C" fn(mp: *const rte_mempool)
+ -> ::std::os::raw::c_uint,
+>;
/// Structure defining mempool operations structure
#[repr(C)]
#[derive(Copy)]
@@ -65,44 +67,88 @@ pub struct rte_mempool_ops {
}
#[test]
fn bindgen_test_layout_rte_mempool_ops() {
- assert_eq!(::std::mem::size_of::<rte_mempool_ops>() , 128usize , concat !
- ( "Size of: " , stringify ! ( rte_mempool_ops ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . name as * const _
- as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( name ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . alloc as * const _
- as usize } , 32usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( alloc ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . free as * const _
- as usize } , 40usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( free ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . enqueue as * const
- _ as usize } , 48usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( enqueue ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . dequeue as * const
- _ as usize } , 56usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( dequeue ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops ) ) . get_count as *
- const _ as usize } , 64usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops ) ,
- "::" , stringify ! ( get_count ) ));
+ assert_eq!(
+ ::std::mem::size_of::<rte_mempool_ops>(),
+ 128usize,
+ concat!("Size of: ", stringify!(rte_mempool_ops))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).name as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(name)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).alloc as *const _ as usize },
+ 32usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(alloc)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).free as *const _ as usize },
+ 40usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(free)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).enqueue as *const _ as usize },
+ 48usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(enqueue)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).dequeue as *const _ as usize },
+ 56usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(dequeue)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops)).get_count as *const _ as usize },
+ 64usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops),
+ "::",
+ stringify!(get_count)
+ )
+ );
}
impl Clone for rte_mempool_ops {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for rte_mempool_ops {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for rte_mempool_ops {
+ fn eq(&self, other: &rte_mempool_ops) -> bool {
+ self.name == other.name && self.alloc == other.alloc && self.free == other.free
+ && self.enqueue == other.enqueue && self.dequeue == other.dequeue
+ && self.get_count == other.get_count
+ }
}
/// The rte_spinlock_t type.
#[repr(C)]
@@ -113,18 +159,31 @@ pub struct rte_spinlock_t {
}
#[test]
fn bindgen_test_layout_rte_spinlock_t() {
- assert_eq!(::std::mem::size_of::<rte_spinlock_t>() , 4usize , concat ! (
- "Size of: " , stringify ! ( rte_spinlock_t ) ));
- assert_eq! (::std::mem::align_of::<rte_spinlock_t>() , 4usize , concat ! (
- "Alignment of " , stringify ! ( rte_spinlock_t ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_spinlock_t ) ) . locked as * const _
- as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_spinlock_t ) , "::"
- , stringify ! ( locked ) ));
+ assert_eq!(
+ ::std::mem::size_of::<rte_spinlock_t>(),
+ 4usize,
+ concat!("Size of: ", stringify!(rte_spinlock_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<rte_spinlock_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(rte_spinlock_t))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_spinlock_t)).locked as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_spinlock_t),
+ "::",
+ stringify!(locked)
+ )
+ );
}
impl Clone for rte_spinlock_t {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
/// Structure storing the table of registered ops structs, each of which contain
/// the function pointers for the mempool ops functions.
@@ -146,30 +205,51 @@ pub struct rte_mempool_ops_table {
}
#[test]
fn bindgen_test_layout_rte_mempool_ops_table() {
- assert_eq!(::std::mem::size_of::<rte_mempool_ops_table>() , 2112usize ,
- concat ! ( "Size of: " , stringify ! ( rte_mempool_ops_table )
- ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops_table ) ) . sl as * const
- _ as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops_table )
- , "::" , stringify ! ( sl ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops_table ) ) . num_ops as *
- const _ as usize } , 4usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops_table )
- , "::" , stringify ! ( num_ops ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const rte_mempool_ops_table ) ) . ops as *
- const _ as usize } , 64usize , concat ! (
- "Alignment of field: " , stringify ! ( rte_mempool_ops_table )
- , "::" , stringify ! ( ops ) ));
+ assert_eq!(
+ ::std::mem::size_of::<rte_mempool_ops_table>(),
+ 2112usize,
+ concat!("Size of: ", stringify!(rte_mempool_ops_table))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops_table)).sl as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops_table),
+ "::",
+ stringify!(sl)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops_table)).num_ops as *const _ as usize },
+ 4usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops_table),
+ "::",
+ stringify!(num_ops)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const rte_mempool_ops_table)).ops as *const _ as usize },
+ 64usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(rte_mempool_ops_table),
+ "::",
+ stringify!(ops)
+ )
+ );
}
impl Clone for rte_mempool_ops_table {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for rte_mempool_ops_table {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
/// Structure to hold malloc heap
#[repr(C)]
@@ -187,56 +267,100 @@ pub struct malloc_heap__bindgen_ty_1 {
}
#[test]
fn bindgen_test_layout_malloc_heap__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<malloc_heap__bindgen_ty_1>() , 8usize ,
- concat ! (
- "Size of: " , stringify ! ( malloc_heap__bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<malloc_heap__bindgen_ty_1>() , 8usize ,
- concat ! (
- "Alignment of " , stringify ! ( malloc_heap__bindgen_ty_1 )
- ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const malloc_heap__bindgen_ty_1 ) ) . lh_first
- as * const _ as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! (
- malloc_heap__bindgen_ty_1 ) , "::" , stringify ! ( lh_first )
- ));
+ assert_eq!(
+ ::std::mem::size_of::<malloc_heap__bindgen_ty_1>(),
+ 8usize,
+ concat!("Size of: ", stringify!(malloc_heap__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<malloc_heap__bindgen_ty_1>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(malloc_heap__bindgen_ty_1))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const malloc_heap__bindgen_ty_1)).lh_first as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(malloc_heap__bindgen_ty_1),
+ "::",
+ stringify!(lh_first)
+ )
+ );
}
impl Clone for malloc_heap__bindgen_ty_1 {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for malloc_heap__bindgen_ty_1 {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[test]
fn bindgen_test_layout_malloc_heap() {
- assert_eq!(::std::mem::size_of::<malloc_heap>() , 128usize , concat ! (
- "Size of: " , stringify ! ( malloc_heap ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const malloc_heap ) ) . lock as * const _ as
- usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( malloc_heap ) , "::" ,
- stringify ! ( lock ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const malloc_heap ) ) . free_head as * const _
- as usize } , 8usize , concat ! (
- "Alignment of field: " , stringify ! ( malloc_heap ) , "::" ,
- stringify ! ( free_head ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const malloc_heap ) ) . alloc_count as * const
- _ as usize } , 112usize , concat ! (
- "Alignment of field: " , stringify ! ( malloc_heap ) , "::" ,
- stringify ! ( alloc_count ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const malloc_heap ) ) . total_size as * const _
- as usize } , 120usize , concat ! (
- "Alignment of field: " , stringify ! ( malloc_heap ) , "::" ,
- stringify ! ( total_size ) ));
+ assert_eq!(
+ ::std::mem::size_of::<malloc_heap>(),
+ 128usize,
+ concat!("Size of: ", stringify!(malloc_heap))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const malloc_heap)).lock as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(malloc_heap),
+ "::",
+ stringify!(lock)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const malloc_heap)).free_head as *const _ as usize },
+ 8usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(malloc_heap),
+ "::",
+ stringify!(free_head)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const malloc_heap)).alloc_count as *const _ as usize },
+ 112usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(malloc_heap),
+ "::",
+ stringify!(alloc_count)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const malloc_heap)).total_size as *const _ as usize },
+ 120usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(malloc_heap),
+ "::",
+ stringify!(total_size)
+ )
+ );
}
impl Clone for malloc_heap {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for malloc_heap {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for malloc_heap {
+ fn eq(&self, other: &malloc_heap) -> bool {
+ self.lock == other.lock && self.free_head == other.free_head
+ && self.alloc_count == other.alloc_count && self.total_size == other.total_size
+ }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Hash, PartialEq, Eq)]
@@ -244,5 +368,7 @@ pub struct malloc_elem {
pub _address: u8,
}
impl Clone for malloc_elem {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
diff --git a/tests/expectations/tests/layout_array_too_long.rs b/tests/expectations/tests/layout_array_too_long.rs
index 1a3da41e..6cfd85a4 100644
--- a/tests/expectations/tests/layout_array_too_long.rs
+++ b/tests/expectations/tests/layout_array_too_long.rs
@@ -31,31 +31,56 @@ pub struct ip_frag {
}
#[test]
fn bindgen_test_layout_ip_frag() {
- assert_eq!(::std::mem::size_of::<ip_frag>() , 16usize , concat ! (
- "Size of: " , stringify ! ( ip_frag ) ));
- assert_eq! (::std::mem::align_of::<ip_frag>() , 8usize , concat ! (
- "Alignment of " , stringify ! ( ip_frag ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag ) ) . ofs as * const _ as usize }
- , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag ) , "::" ,
- stringify ! ( ofs ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag ) ) . len as * const _ as usize }
- , 2usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag ) , "::" ,
- stringify ! ( len ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag ) ) . mb as * const _ as usize }
- , 8usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag ) , "::" ,
- stringify ! ( mb ) ));
+ assert_eq!(
+ ::std::mem::size_of::<ip_frag>(),
+ 16usize,
+ concat!("Size of: ", stringify!(ip_frag))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ip_frag>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(ip_frag))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag)).ofs as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag),
+ "::",
+ stringify!(ofs)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag)).len as *const _ as usize },
+ 2usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag),
+ "::",
+ stringify!(len)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag)).mb as *const _ as usize },
+ 8usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag),
+ "::",
+ stringify!(mb)
+ )
+ );
}
impl Clone for ip_frag {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for ip_frag {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
/// @internal <src addr, dst_addr, id> to uniquely indetify fragmented datagram.
#[repr(C)]
@@ -70,28 +95,51 @@ pub struct ip_frag_key {
}
#[test]
fn bindgen_test_layout_ip_frag_key() {
- assert_eq!(::std::mem::size_of::<ip_frag_key>() , 40usize , concat ! (
- "Size of: " , stringify ! ( ip_frag_key ) ));
- assert_eq! (::std::mem::align_of::<ip_frag_key>() , 8usize , concat ! (
- "Alignment of " , stringify ! ( ip_frag_key ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_key ) ) . src_dst as * const _ as
- usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_key ) , "::" ,
- stringify ! ( src_dst ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_key ) ) . id as * const _ as
- usize } , 32usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_key ) , "::" ,
- stringify ! ( id ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_key ) ) . key_len as * const _ as
- usize } , 36usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_key ) , "::" ,
- stringify ! ( key_len ) ));
+ assert_eq!(
+ ::std::mem::size_of::<ip_frag_key>(),
+ 40usize,
+ concat!("Size of: ", stringify!(ip_frag_key))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ip_frag_key>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(ip_frag_key))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_key)).src_dst as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_key),
+ "::",
+ stringify!(src_dst)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_key)).id as *const _ as usize },
+ 32usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_key),
+ "::",
+ stringify!(id)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_key)).key_len as *const _ as usize },
+ 36usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_key),
+ "::",
+ stringify!(key_len)
+ )
+ );
}
impl Clone for ip_frag_key {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
/// @internal Fragmented packet to reassemble.
/// First two entries in the frags[] array are for the last and first fragments.
@@ -122,77 +170,141 @@ pub struct ip_frag_pkt__bindgen_ty_1 {
}
#[test]
fn bindgen_test_layout_ip_frag_pkt__bindgen_ty_1() {
- assert_eq!(::std::mem::size_of::<ip_frag_pkt__bindgen_ty_1>() , 16usize ,
- concat ! (
- "Size of: " , stringify ! ( ip_frag_pkt__bindgen_ty_1 ) ));
- assert_eq! (::std::mem::align_of::<ip_frag_pkt__bindgen_ty_1>() , 8usize ,
- concat ! (
- "Alignment of " , stringify ! ( ip_frag_pkt__bindgen_ty_1 )
- ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt__bindgen_ty_1 ) ) . tqe_next
- as * const _ as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! (
- ip_frag_pkt__bindgen_ty_1 ) , "::" , stringify ! ( tqe_next )
- ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt__bindgen_ty_1 ) ) . tqe_prev
- as * const _ as usize } , 8usize , concat ! (
- "Alignment of field: " , stringify ! (
- ip_frag_pkt__bindgen_ty_1 ) , "::" , stringify ! ( tqe_prev )
- ));
+ assert_eq!(
+ ::std::mem::size_of::<ip_frag_pkt__bindgen_ty_1>(),
+ 16usize,
+ concat!("Size of: ", stringify!(ip_frag_pkt__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ip_frag_pkt__bindgen_ty_1>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(ip_frag_pkt__bindgen_ty_1))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt__bindgen_ty_1)).tqe_next as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt__bindgen_ty_1),
+ "::",
+ stringify!(tqe_next)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt__bindgen_ty_1)).tqe_prev as *const _ as usize },
+ 8usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt__bindgen_ty_1),
+ "::",
+ stringify!(tqe_prev)
+ )
+ );
}
impl Clone for ip_frag_pkt__bindgen_ty_1 {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for ip_frag_pkt__bindgen_ty_1 {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
}
#[test]
fn bindgen_test_layout_ip_frag_pkt() {
- assert_eq!(::std::mem::size_of::<ip_frag_pkt>() , 192usize , concat ! (
- "Size of: " , stringify ! ( ip_frag_pkt ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . lru as * const _ as
- usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( lru ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . key as * const _ as
- usize } , 16usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( key ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . start as * const _ as
- usize } , 56usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( start ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . total_size as * const _
- as usize } , 64usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( total_size ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . frag_size as * const _
- as usize } , 68usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( frag_size ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . last_idx as * const _
- as usize } , 72usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( last_idx ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ip_frag_pkt ) ) . frags as * const _ as
- usize } , 80usize , concat ! (
- "Alignment of field: " , stringify ! ( ip_frag_pkt ) , "::" ,
- stringify ! ( frags ) ));
+ assert_eq!(
+ ::std::mem::size_of::<ip_frag_pkt>(),
+ 192usize,
+ concat!("Size of: ", stringify!(ip_frag_pkt))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).lru as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(lru)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).key as *const _ as usize },
+ 16usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(key)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).start as *const _ as usize },
+ 56usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(start)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).total_size as *const _ as usize },
+ 64usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(total_size)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).frag_size as *const _ as usize },
+ 68usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(frag_size)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).last_idx as *const _ as usize },
+ 72usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(last_idx)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ip_frag_pkt)).frags as *const _ as usize },
+ 80usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ip_frag_pkt),
+ "::",
+ stringify!(frags)
+ )
+ );
}
impl Clone for ip_frag_pkt {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
impl Default for ip_frag_pkt {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for ip_frag_pkt {
+ fn eq(&self, other: &ip_frag_pkt) -> bool {
+ self.lru == other.lru && self.key == other.key && self.start == other.start &&
+ self.total_size == other.total_size && self.frag_size == other.frag_size &&
+ self.last_idx == other.last_idx && self.frags == other.frags
+ }
}
/// < fragment mbuf
#[repr(C)]
@@ -201,5 +313,7 @@ pub struct rte_mbuf {
pub _address: u8,
}
impl Clone for rte_mbuf {
- fn clone(&self) -> Self { *self }
+ fn clone(&self) -> Self {
+ *self
+ }
}
diff --git a/tests/expectations/tests/opaque-template-inst-member.rs b/tests/expectations/tests/opaque-template-inst-member.rs
index 0bef4c86..f686150c 100644
--- a/tests/expectations/tests/opaque-template-inst-member.rs
+++ b/tests/expectations/tests/opaque-template-inst-member.rs
@@ -6,10 +6,9 @@
#[repr(C)]
#[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
-/// Debug/Hash/PartialEq because the instantiation's definition cannot derive Debug/Hash/PartialEq.
+pub struct OpaqueTemplate {}
+/// This should not end up deriving Debug/Hash because its `mBlah` field cannot derive
+/// Debug/Hash because the instantiation's definition cannot derive Debug/Hash.
#[repr(C)]
pub struct ContainsOpaqueTemplate {
pub mBlah: [u32; 101usize],
@@ -17,27 +16,48 @@ pub struct ContainsOpaqueTemplate {
}
#[test]
fn bindgen_test_layout_ContainsOpaqueTemplate() {
- assert_eq!(::std::mem::size_of::<ContainsOpaqueTemplate>() , 408usize ,
- concat ! ( "Size of: " , stringify ! ( ContainsOpaqueTemplate )
- ));
- assert_eq! (::std::mem::align_of::<ContainsOpaqueTemplate>() , 4usize ,
- concat ! (
- "Alignment of " , stringify ! ( ContainsOpaqueTemplate ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBlah as *
- const _ as usize } , 0usize , concat ! (
- "Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
- ) , "::" , stringify ! ( mBlah ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBaz as *
- const _ as usize } , 404usize , concat ! (
- "Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
- ) , "::" , stringify ! ( mBaz ) ));
+ assert_eq!(
+ ::std::mem::size_of::<ContainsOpaqueTemplate>(),
+ 408usize,
+ concat!("Size of: ", stringify!(ContainsOpaqueTemplate))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<ContainsOpaqueTemplate>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(ContainsOpaqueTemplate))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ContainsOpaqueTemplate)).mBlah as *const _ as usize },
+ 0usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ContainsOpaqueTemplate),
+ "::",
+ stringify!(mBlah)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const ContainsOpaqueTemplate)).mBaz as *const _ as usize },
+ 404usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(ContainsOpaqueTemplate),
+ "::",
+ stringify!(mBaz)
+ )
+ );
}
impl Default for ContainsOpaqueTemplate {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for ContainsOpaqueTemplate {
+ fn eq(&self, other: &ContainsOpaqueTemplate) -> bool {
+ &self.mBlah[..] == &other.mBlah[..] && self.mBaz == other.mBaz
+ }
}
-/// This shold not end up deriving Debug/Hash/PartialEq either, for similar reasons, although
+/// This should not end up deriving Debug/Hash either, for similar reasons, although
/// we're exercising base member edges now.
#[repr(C)]
pub struct InheritsOpaqueTemplate {
@@ -46,18 +66,34 @@ pub struct InheritsOpaqueTemplate {
}
#[test]
fn bindgen_test_layout_InheritsOpaqueTemplate() {
- assert_eq!(::std::mem::size_of::<InheritsOpaqueTemplate>() , 416usize ,
- concat ! ( "Size of: " , stringify ! ( InheritsOpaqueTemplate )
- ));
- assert_eq! (::std::mem::align_of::<InheritsOpaqueTemplate>() , 8usize ,
- concat ! (
- "Alignment of " , stringify ! ( InheritsOpaqueTemplate ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const InheritsOpaqueTemplate ) ) . wow as *
- const _ as usize } , 408usize , concat ! (
- "Alignment of field: " , stringify ! ( InheritsOpaqueTemplate
- ) , "::" , stringify ! ( wow ) ));
+ assert_eq!(
+ ::std::mem::size_of::<InheritsOpaqueTemplate>(),
+ 416usize,
+ concat!("Size of: ", stringify!(InheritsOpaqueTemplate))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<InheritsOpaqueTemplate>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(InheritsOpaqueTemplate))
+ );
+ assert_eq!(
+ unsafe { &(*(0 as *const InheritsOpaqueTemplate)).wow as *const _ as usize },
+ 408usize,
+ concat!(
+ "Alignment of field: ",
+ stringify!(InheritsOpaqueTemplate),
+ "::",
+ stringify!(wow)
+ )
+ );
}
impl Default for InheritsOpaqueTemplate {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl ::std::cmp::PartialEq for InheritsOpaqueTemplate {
+ fn eq(&self, other: &InheritsOpaqueTemplate) -> bool {
+ &self._base[..] == &other._base[..] && self.wow == other.wow
+ }
}
diff --git a/tests/headers/class_1_0.hpp b/tests/headers/class_1_0.hpp
index ee00c2b7..6fa01e95 100644
--- a/tests/headers/class_1_0.hpp
+++ b/tests/headers/class_1_0.hpp
@@ -1,4 +1,4 @@
-// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --with-derive-eq
+// bindgen-flags: --rust-target 1.0 --with-derive-hash --with-derive-partialeq --impl-partialeq --with-derive-eq
class C {
int a;
diff --git a/tests/headers/derive-partialeq-anonfield.h b/tests/headers/derive-partialeq-anonfield.h
new file mode 100644
index 00000000..3bbe2bc3
--- /dev/null
+++ b/tests/headers/derive-partialeq-anonfield.h
@@ -0,0 +1,5 @@
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq
+
+struct rte_mbuf {
+ union {};
+} __attribute__((__aligned__(64)));
diff --git a/tests/headers/derive-partialeq-base.hpp b/tests/headers/derive-partialeq-base.hpp
new file mode 100644
index 00000000..989cbe69
--- /dev/null
+++ b/tests/headers/derive-partialeq-base.hpp
@@ -0,0 +1,8 @@
+// bindgen-flags: --with-derive-partialeq --impl-partialeq
+
+class Base {
+ int large[33];
+};
+
+class ShouldDerivePartialEq: Base {
+};
diff --git a/tests/headers/derive-partialeq-bitfield.hpp b/tests/headers/derive-partialeq-bitfield.hpp
new file mode 100644
index 00000000..ac2cac63
--- /dev/null
+++ b/tests/headers/derive-partialeq-bitfield.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --with-derive-partialeq --impl-partialeq
+
+class C {
+ bool a: 1;
+ bool b: 7;
+ int large_array[50];
+};
diff --git a/tests/headers/derive-partialeq-core.h b/tests/headers/derive-partialeq-core.h
new file mode 100644
index 00000000..6da5b786
--- /dev/null
+++ b/tests/headers/derive-partialeq-core.h
@@ -0,0 +1,5 @@
+// bindgen-flags: --with-derive-partialeq --impl-partialeq --use-core --raw-line "extern crate core;"
+
+struct C {
+ int large_array[420];
+};
diff --git a/tests/headers/derive-partialeq-pointer.hpp b/tests/headers/derive-partialeq-pointer.hpp
new file mode 100644
index 00000000..ce971e07
--- /dev/null
+++ b/tests/headers/derive-partialeq-pointer.hpp
@@ -0,0 +1,12 @@
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq
+
+struct a;
+class Bar {
+ a *b;
+};
+struct c {
+ union {};
+};
+struct a {
+ c d;
+};
diff --git a/tests/headers/derive-partialeq-union.hpp b/tests/headers/derive-partialeq-union.hpp
new file mode 100644
index 00000000..887506d0
--- /dev/null
+++ b/tests/headers/derive-partialeq-union.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --with-derive-partialeq --impl-partialeq
+
+// Deriving PartialEq for rust unions is not supported.
+union ShouldNotDerivePartialEq {
+ char a;
+ int b;
+};
diff --git a/tests/headers/derive-partialeq-union_1_0.hpp b/tests/headers/derive-partialeq-union_1_0.hpp
new file mode 100644
index 00000000..846a00dd
--- /dev/null
+++ b/tests/headers/derive-partialeq-union_1_0.hpp
@@ -0,0 +1,7 @@
+// bindgen-flags: --rust-target 1.0 --with-derive-partialeq --impl-partialeq
+
+// This should manually derive PartialEq.
+union ShouldDerivePartialEq {
+ char a[150];
+ int b;
+};
diff --git a/tests/headers/issue-648-derive-debug-with-padding.h b/tests/headers/issue-648-derive-debug-with-padding.h
index c9ec0210..f528c100 100644
--- a/tests/headers/issue-648-derive-debug-with-padding.h
+++ b/tests/headers/issue-648-derive-debug-with-padding.h
@@ -1,4 +1,4 @@
-// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq
/**
* We emit a `[u8; 63usize]` padding field for this struct, which cannot derive
* Debug/Hash because 63 is over the hard coded limit. (Yes, this struct doesn't end
diff --git a/tests/headers/layout_array.h b/tests/headers/layout_array.h
index 6a20f7c3..239e52b1 100644
--- a/tests/headers/layout_array.h
+++ b/tests/headers/layout_array.h
@@ -1,4 +1,4 @@
-// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
diff --git a/tests/headers/layout_array_too_long.h b/tests/headers/layout_array_too_long.h
index a3ef3d20..1d8b1b63 100644
--- a/tests/headers/layout_array_too_long.h
+++ b/tests/headers/layout_array_too_long.h
@@ -1,4 +1,4 @@
-// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --rustified-enum .*
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq --rustified-enum .*
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
diff --git a/tests/headers/opaque-template-inst-member.hpp b/tests/headers/opaque-template-inst-member.hpp
index 4cb3dd72..6516aa56 100644
--- a/tests/headers/opaque-template-inst-member.hpp
+++ b/tests/headers/opaque-template-inst-member.hpp
@@ -1,4 +1,4 @@
-// bindgen-flags: --opaque-type 'OpaqueTemplate' --with-derive-hash --with-derive-partialeq --with-derive-eq
+// bindgen-flags: --opaque-type 'OpaqueTemplate' --with-derive-hash --with-derive-partialeq --impl-partialeq --with-derive-eq
template<typename T>
class OpaqueTemplate {
@@ -6,14 +6,14 @@ class OpaqueTemplate {
bool mCannotDebug[400];
};
-/// This should not end up deriving Debug/Hash/PartialEq because its `mBlah` field cannot derive
-/// Debug/Hash/PartialEq because the instantiation's definition cannot derive Debug/Hash/PartialEq.
+/// This should not end up deriving Debug/Hash because its `mBlah` field cannot derive
+/// Debug/Hash because the instantiation's definition cannot derive Debug/Hash.
class ContainsOpaqueTemplate {
OpaqueTemplate<int> mBlah;
int mBaz;
};
-/// This shold not end up deriving Debug/Hash/PartialEq either, for similar reasons, although
+/// This should not end up deriving Debug/Hash either, for similar reasons, although
/// we're exercising base member edges now.
class InheritsOpaqueTemplate : public OpaqueTemplate<bool> {
char* wow;