diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 4ae0bfebe5..637e3a65d3 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1418,7 +1418,7 @@ impl CodeGenerator for CompInfo { derives.push("Debug"); } - if item.can_derive_default(ctx, ()) { + if item.can_derive_default(ctx) { derives.push("Default"); } else { needs_default_impl = ctx.options().derive_default; diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs new file mode 100644 index 0000000000..de74177db6 --- /dev/null +++ b/src/ir/analysis/derive_default.rs @@ -0,0 +1,360 @@ +//! Determining which types for which we can emit `#[derive(Default)]`. + +use super::{ConstrainResult, MonotoneFramework, HasVtable}; +use std::collections::HashSet; +use std::collections::HashMap; +use ir::context::{BindgenContext, ItemId}; +use ir::item::IsOpaque; +use ir::traversal::EdgeKind; +use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; +use ir::ty::TypeKind; +use ir::comp::Field; +use ir::comp::FieldMethods; +use ir::derive::CanTriviallyDeriveDefault; +use ir::comp::CompKind; +use ir::traversal::Trace; +use ir::item::ItemSet; + +/// An analysis that finds for each IR item whether default cannot be derived. +/// +/// We use the monotone constraint function `cannot_derive_default`, defined as +/// follows: +/// +/// * 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, default cannot be derived if the length of the array is +/// larger than the limit or the type of data the array contains cannot derive +/// default. +/// * If T is a type alias, a templated alias or an indirection to another type, +/// default cannot be derived if the type T refers to cannot be derived default. +/// * If T is a compound type, default cannot be derived if any of its base member +/// or field cannot be derived default. +#[derive(Debug, Clone)] +pub struct CannotDeriveDefault<'ctx, 'gen> + where 'gen: 'ctx +{ + ctx: &'ctx BindgenContext<'gen>, + + // The incremental result of this analysis's computation. Everything in this + // set cannot derive debug. + cannot_derive_default: HashSet, + + // Dependencies saying that if a key ItemId has been inserted into the + // `cannot_derive_default` set, then each of the ids in Vec need to be + // considered again. + // + // This is a subset of the natural IR graph with reversed edges, where we + // only include the edges from the IR graph that can affect whether a type + // can derive debug or not. + dependencies: HashMap>, +} + +impl<'ctx, 'gen> CannotDeriveDefault<'ctx, 'gen> { + fn consider_edge(kind: EdgeKind) -> bool { + match kind { + // These are the only edges that can affect whether a type can derive + // debug or not. + EdgeKind::BaseMember | + EdgeKind::Field | + EdgeKind::TypeReference | + EdgeKind::VarType | + EdgeKind::TemplateArgument | + EdgeKind::TemplateDeclaration | + EdgeKind::TemplateParameterDefinition => true, + + EdgeKind::Constructor | + EdgeKind::Destructor | + EdgeKind::FunctionReturn | + EdgeKind::FunctionParameter | + EdgeKind::InnerType | + EdgeKind::InnerVar | + EdgeKind::Method => false, + EdgeKind::Generic => false, + } + } + + fn insert(&mut self, id: ItemId) -> ConstrainResult { + trace!("inserting {:?} into the cannot_derive_default set", id); + + let was_not_already_in_set = self.cannot_derive_default.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 + ); + + ConstrainResult::Changed + } +} + +impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> { + type Node = ItemId; + type Extra = &'ctx BindgenContext<'gen>; + type Output = HashSet; + + fn new(ctx: &'ctx BindgenContext<'gen>) -> CannotDeriveDefault<'ctx, 'gen> { + let mut dependencies = HashMap::new(); + let cannot_derive_default = HashSet::new(); + + let whitelisted_items: HashSet<_> = ctx.whitelisted_items() + .iter() + .cloned() + .collect(); + + let whitelisted_and_blacklisted_items: ItemSet = whitelisted_items.iter() + .cloned() + .flat_map(|i| { + let mut reachable = vec![i]; + i.trace(ctx, &mut |s, _| { + reachable.push(s); + }, &()); + reachable + }) + .collect(); + + for item in whitelisted_and_blacklisted_items { + dependencies.entry(item).or_insert(vec![]); + + { + // We reverse our natural IR graph edges to find dependencies + // between nodes. + item.trace(ctx, &mut |sub_item: ItemId, edge_kind| { + if ctx.whitelisted_items().contains(&sub_item) && + Self::consider_edge(edge_kind) { + dependencies.entry(sub_item) + .or_insert(vec![]) + .push(item); + } + }, &()); + } + } + + CannotDeriveDefault { + ctx, + cannot_derive_default, + dependencies, + } + } + + fn initial_worklist(&self) -> Vec { + self.ctx.whitelisted_items().iter().cloned().collect() + } + + fn constrain(&mut self, id: ItemId) -> ConstrainResult { + trace!("constrain: {:?}", id); + + if self.cannot_derive_default.contains(&id) { + trace!(" already know it cannot derive Default"); + 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 ty.is_opaque(self.ctx, item) { + let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { + l.opaque().can_trivially_derive_default() + }); + return if layout_can_derive { + trace!(" we can trivially derive Default for the layout"); + ConstrainResult::Same + } else { + trace!(" we cannot derive Default for the layout"); + self.insert(id) + }; + } + + 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); + } + + match *ty.kind() { + // Handle the simple cases. These can derive debug without further + // information. + TypeKind::Function(..) | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) => { + trace!(" simple type that can always derive Default"); + ConstrainResult::Same + } + + TypeKind::Void | + TypeKind::Named | + TypeKind::Reference(..) | + TypeKind::NullPtr | + TypeKind::Pointer(..) | + TypeKind::BlockPointer | + TypeKind::ObjCId | + TypeKind::ObjCSel | + TypeKind::ObjCInterface(..) | + TypeKind::Enum(..) => { + trace!(" types that always cannot derive Default"); + self.insert(id) + } + + TypeKind::Array(t, len) => { + if self.cannot_derive_default.contains(&t) { + trace!(" arrays of T for which we cannot derive Default \ + also cannot derive Default"); + return self.insert(id); + } + + if len <= RUST_DERIVE_IN_ARRAY_LIMIT { + trace!(" array is small enough to derive Default"); + ConstrainResult::Same + } else { + trace!(" array is too large to derive Default"); + self.insert(id) + } + } + + TypeKind::ResolvedTypeRef(t) | + TypeKind::TemplateAlias(t, _) | + TypeKind::Alias(t) => { + if self.cannot_derive_default.contains(&t) { + trace!(" aliases and type refs to T which cannot derive \ + Default also cannot derive Default"); + self.insert(id) + } else { + trace!(" aliases and type refs to T which can derive \ + Default can also derive Default"); + ConstrainResult::Same + } + } + + TypeKind::Comp(ref info) => { + assert!( + !info.has_non_type_template_params(), + "The early ty.is_opaque check should have handled this case" + ); + + if info.kind() == CompKind::Union { + if self.ctx.options().unstable_rust { + trace!(" cannot derive Default for Rust unions"); + return self.insert(id); + } + + if ty.layout(self.ctx) + .map_or(true, + |l| l.opaque().can_trivially_derive_default()) { + trace!(" union layout can trivially derive Default"); + return ConstrainResult::Same; + } else { + trace!(" union layout cannot derive Default"); + return self.insert(id); + } + } + + if item.has_vtable(self.ctx) { + trace!(" comp with vtable cannot derive Default"); + return self.insert(id); + } + + let bases_cannot_derive = info.base_members() + .iter() + .any(|base| self.cannot_derive_default.contains(&base.ty)); + if bases_cannot_derive { + trace!(" base members cannot derive Default, so we can't \ + either"); + return self.insert(id); + } + + let fields_cannot_derive = info.fields() + .iter() + .any(|f| { + match *f { + Field::DataMember(ref data) => { + self.cannot_derive_default.contains(&data.ty()) + } + Field::Bitfields(ref bfu) => { + bfu.bitfields() + .iter().any(|b| { + self.cannot_derive_default.contains(&b.ty()) + }) + } + } + }); + if fields_cannot_derive { + trace!(" fields cannot derive Default, so we can't either"); + return self.insert(id); + } + + trace!(" comp can derive Default"); + ConstrainResult::Same + } + + TypeKind::TemplateInstantiation(ref template) => { + if self.ctx.whitelisted_items().contains(&template.template_definition()) { + let args_cannot_derive = template.template_arguments() + .iter() + .any(|arg| self.cannot_derive_default.contains(&arg)); + if args_cannot_derive { + trace!(" template args cannot derive Default, so \ + insantiation can't either"); + return self.insert(id); + } + + assert!( + !template.template_definition().is_opaque(self.ctx, &()), + "The early ty.is_opaque check should have handled this case" + ); + let def_cannot_derive = self.cannot_derive_default + .contains(&template.template_definition()); + if def_cannot_derive { + trace!(" template definition cannot derive Default, so \ + insantiation can't either"); + return self.insert(id); + } + + trace!(" template instantiation can derive Default"); + ConstrainResult::Same + } else { + trace!(" blacklisted template instantiation cannot derive default"); + return self.insert(id); + } + } + + TypeKind::Opaque => { + unreachable!( + "The early ty.is_opaque check should have handled this case" + ) + } + + TypeKind::UnresolvedTypeRef(..) => { + unreachable!( + "Type with unresolved type ref can't reach derive default" + ) + } + } + } + + fn each_depending_on(&self, id: ItemId, mut f: F) + where F: FnMut(ItemId), + { + if let Some(edges) = self.dependencies.get(&id) { + for item in edges { + trace!("enqueue {:?} into worklist", item); + f(*item); + } + } + } +} + +impl<'ctx, 'gen> From> for HashSet { + fn from(analysis: CannotDeriveDefault<'ctx, 'gen>) -> Self { + analysis.cannot_derive_default + } +} diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs index 8a00ecce55..ec150ec462 100644 --- a/src/ir/analysis/mod.rs +++ b/src/ir/analysis/mod.rs @@ -45,6 +45,8 @@ pub use self::derive_debug::CannotDeriveDebug; mod has_vtable; pub use self::has_vtable::HasVtableAnalysis; pub use self::has_vtable::HasVtable; +mod derive_default; +pub use self::derive_default::CannotDeriveDefault; use ir::context::{BindgenContext, ItemId}; use ir::traversal::{EdgeKind, Trace}; diff --git a/src/ir/comp.rs b/src/ir/comp.rs index c2e9bd8ff4..b3cb3ca52e 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -2,12 +2,12 @@ use super::annotations::Annotations; use super::context::{BindgenContext, ItemId}; -use super::derive::{CanDeriveCopy, CanDeriveDefault}; +use super::derive::CanDeriveCopy; use super::dot::DotAttributes; use super::item::{IsOpaque, Item}; use super::layout::Layout; use super::traversal::{EdgeKind, Trace, Tracer}; -use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT; +// use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT; use super::template::TemplateParameters; use clang; use codegen::struct_layout::{align_to, bytes_from_bits_pow2}; @@ -702,19 +702,6 @@ impl FieldMethods for FieldData { } } -impl<'a> CanDeriveDefault<'a> for Field { - type Extra = (); - - fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool { - match *self { - Field::DataMember(ref data) => data.ty.can_derive_default(ctx, ()), - Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => bitfields.iter().all(|b| { - b.ty().can_derive_default(ctx, ()) - }), - } - } -} - impl<'a> CanDeriveCopy<'a> for Field { type Extra = (); @@ -845,10 +832,6 @@ pub struct CompInfo { /// and pray, or behave as an opaque type. found_unknown_attr: bool, - /// Used to detect if we've run in a can_derive_default cycle while cycling - /// around the template arguments. - detect_derive_default_cycle: Cell, - /// Used to detect if we've run in a has_destructor cycle while cycling /// around the template arguments. detect_has_destructor_cycle: Cell, @@ -877,7 +860,6 @@ impl CompInfo { has_non_type_template_params: false, packed: false, found_unknown_attr: false, - detect_derive_default_cycle: Cell::new(false), detect_has_destructor_cycle: Cell::new(false), is_forward_declaration: false, } @@ -1422,53 +1404,6 @@ impl TemplateParameters for CompInfo { } } -impl<'a> CanDeriveDefault<'a> for CompInfo { - type Extra = (&'a Item, Option); - - fn can_derive_default(&self, - ctx: &BindgenContext, - (item, layout): (&Item, Option)) - -> bool { - // We can reach here recursively via template parameters of a member, - // for example. - if self.detect_derive_default_cycle.get() { - warn!("Derive default cycle detected!"); - return true; - } - - if layout.map_or(false, |l| l.align > RUST_DERIVE_IN_ARRAY_LIMIT) { - return false; - } - - if self.kind == CompKind::Union { - if ctx.options().unstable_rust { - return false; - } - - return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ())); - } - - if self.has_non_type_template_params { - return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ())); - } - - self.detect_derive_default_cycle.set(true); - - let can_derive_default = !ctx.lookup_item_id_has_vtable(&item.id()) && - !self.needs_explicit_vtable(ctx, item) && - self.base_members - .iter() - .all(|base| base.ty.can_derive_default(ctx, ())) && - self.fields() - .iter() - .all(|f| f.can_derive_default(ctx, ())); - - self.detect_derive_default_cycle.set(false); - - can_derive_default - } -} - impl<'a> CanDeriveCopy<'a> for CompInfo { type Extra = (&'a Item, Option); diff --git a/src/ir/context.rs b/src/ir/context.rs index 6c38e8e75a..d9281a23d4 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -5,7 +5,8 @@ use super::int::IntKind; use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet}; use super::item_kind::ItemKind; use super::module::{Module, ModuleKind}; -use super::analysis::{analyze, UsedTemplateParameters, CannotDeriveDebug, HasVtableAnalysis}; +use super::analysis::{analyze, UsedTemplateParameters, CannotDeriveDebug, HasVtableAnalysis, + CannotDeriveDefault}; use super::template::{TemplateInstantiation, TemplateParameters}; use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, Type, TypeKind}; @@ -45,11 +46,9 @@ impl CanDeriveDebug for ItemId { } } -impl<'a> CanDeriveDefault<'a> for ItemId { - type Extra = (); - - fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool { - ctx.resolve_item(*self).can_derive_default(ctx, ()) +impl CanDeriveDefault for ItemId { + fn can_derive_default(&self, ctx: &BindgenContext) -> bool { + ctx.options().derive_default && ctx.lookup_item_id_can_derive_default(*self) } } @@ -183,6 +182,12 @@ pub struct BindgenContext<'ctx> { /// and is always `None` before that and `Some` after. cant_derive_debug: Option>, + /// The set of (`ItemId`s of) types that can't derive default. + /// + /// This is populated when we enter codegen by `compute_can_derive_default` + /// and is always `None` before that and `Some` after. + cannot_derive_default: Option>, + /// The set of (`ItemId's of`) types that has vtable. /// /// Populated when we enter codegen by `compute_has_vtable`; always `None` @@ -314,6 +319,7 @@ impl<'ctx> BindgenContext<'ctx> { need_bitfield_allocation: Default::default(), needs_mangling_hack: needs_mangling_hack, cant_derive_debug: None, + cannot_derive_default: None, have_vtable: None, }; @@ -788,6 +794,7 @@ impl<'ctx> BindgenContext<'ctx> { self.compute_has_vtable(); self.find_used_template_parameters(); self.compute_cant_derive_debug(); + self.compute_cannot_derive_default(); let ret = cb(self); self.gen_ctx = None; @@ -1770,6 +1777,23 @@ impl<'ctx> BindgenContext<'ctx> { // derive debug or not. !self.cant_derive_debug.as_ref().unwrap().contains(&id) } + + /// Compute whether we can derive default. + fn compute_cannot_derive_default(&mut self) { + assert!(self.cannot_derive_default.is_none()); + self.cannot_derive_default = Some(analyze::(self)); + } + + /// Look up whether the item with `id` can + /// derive default or not. + pub fn lookup_item_id_can_derive_default(&self, id: ItemId) -> bool { + assert!(self.in_codegen_phase(), + "We only compute can_derive_default when we enter codegen"); + + // Look up the computed value for whether the item with `id` can + // derive default or not. + !self.cannot_derive_default.as_ref().unwrap().contains(&id) + } } /// A builder struct for configuring item resolution options. diff --git a/src/ir/derive.rs b/src/ir/derive.rs index 3334618c02..5bc9cfdd11 100644 --- a/src/ir/derive.rs +++ b/src/ir/derive.rs @@ -82,16 +82,22 @@ pub trait CanDeriveCopy<'a> { /// to be a recursive method that checks whether all the proper members can /// derive default or not, because of the limit rust has on 32 items as max in the /// array. -pub trait CanDeriveDefault<'a> { - /// Implementations can define this type to get access to any extra - /// information required to determine whether they can derive `Default`. If - /// extra information is unneeded, then this should simply be the unit type. - type Extra; +pub trait CanDeriveDefault { /// Return `true` if `Default` can be derived for this thing, `false` /// otherwise. fn can_derive_default(&self, - ctx: &BindgenContext, - extra: Self::Extra) + ctx: &BindgenContext) -> bool; } + +/// A trait that encapsulates the logic for whether or not we can derive `Default`. +/// The difference between this trait and the CanDeriveDefault is that the type +/// implementing this trait cannot use recursion or lookup result from fix point +/// analysis. It's a helper trait for fix point analysis. +pub trait CanTriviallyDeriveDefault { + + /// Return `true` if `Default` can be derived for this thing, `false` + /// otherwise. + fn can_trivially_derive_default(&self) -> bool; +} diff --git a/src/ir/item.rs b/src/ir/item.rs index 92954a8f10..8a210e38a1 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -276,23 +276,9 @@ impl CanDeriveDebug for Item { } } -impl<'a> CanDeriveDefault<'a> for Item { - type Extra = (); - - fn can_derive_default(&self, ctx: &BindgenContext, _: ()) -> bool { - ctx.options().derive_default && - match self.kind { - ItemKind::Type(ref ty) => { - if self.is_opaque(ctx, &()) { - ty.layout(ctx) - .map_or(false, - |l| l.opaque().can_derive_default(ctx, ())) - } else { - ty.can_derive_default(ctx, self) - } - } - _ => false, - } +impl CanDeriveDefault for Item { + fn can_derive_default(&self, ctx: &BindgenContext) -> bool { + ctx.options().derive_default && ctx.lookup_item_id_can_derive_default(self.id()) } } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index 03496ad055..b0ec171ac3 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -1,7 +1,8 @@ //! Intermediate representation for the physical layout of some type. use super::context::BindgenContext; -use super::derive::{CanDeriveCopy, CanTriviallyDeriveDebug, CanDeriveDefault}; +use super::derive::{CanDeriveCopy, CanTriviallyDeriveDebug, + CanTriviallyDeriveDefault}; use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind}; use clang; use std::{cmp, mem}; @@ -111,10 +112,9 @@ impl CanTriviallyDeriveDebug for Opaque { } } -impl<'a> CanDeriveDefault<'a> for Opaque { - type Extra = (); +impl CanTriviallyDeriveDefault for Opaque { - fn can_derive_default(&self, _: &BindgenContext, _: ()) -> bool { + fn can_trivially_derive_default(&self) -> bool { self.array_size() .map_or(false, |size| size <= RUST_DERIVE_IN_ARRAY_LIMIT) } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 1c213569df..b3de1f036e 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -2,7 +2,7 @@ use super::comp::CompInfo; use super::context::{BindgenContext, ItemId}; -use super::derive::{CanDeriveCopy, CanDeriveDefault}; +use super::derive::CanDeriveCopy; use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; @@ -526,46 +526,6 @@ impl TemplateParameters for TypeKind { } } -impl<'a> CanDeriveDefault<'a> for Type { - type Extra = &'a Item; - - fn can_derive_default(&self, ctx: &BindgenContext, item: &Item) -> bool { - match self.kind { - TypeKind::Array(t, len) => { - len <= RUST_DERIVE_IN_ARRAY_LIMIT && - t.can_derive_default(ctx, ()) - } - TypeKind::ResolvedTypeRef(t) | - TypeKind::TemplateAlias(t, _) | - TypeKind::Alias(t) => t.can_derive_default(ctx, ()), - TypeKind::Comp(ref info) => { - info.can_derive_default(ctx, (&item, self.layout(ctx))) - } - TypeKind::Opaque => { - self.layout - .map_or(true, |l| l.opaque().can_derive_default(ctx, ())) - } - TypeKind::Void | - TypeKind::Named | - TypeKind::TemplateInstantiation(..) | - TypeKind::Reference(..) | - TypeKind::NullPtr | - TypeKind::Pointer(..) | - TypeKind::BlockPointer | - TypeKind::ObjCId | - TypeKind::ObjCSel | - TypeKind::ObjCInterface(..) | - TypeKind::Enum(..) => false, - - TypeKind::Function(..) | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) => true, - TypeKind::UnresolvedTypeRef(..) => unreachable!(), - } - } -} - impl<'a> CanDeriveCopy<'a> for Type { type Extra = &'a Item; diff --git a/tests/expectations/tests/crtp.rs b/tests/expectations/tests/crtp.rs index 0b761d52eb..f2b1dbd853 100644 --- a/tests/expectations/tests/crtp.rs +++ b/tests/expectations/tests/crtp.rs @@ -10,7 +10,7 @@ pub struct Base { pub _address: u8, } #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct Derived { pub _address: u8, } @@ -24,16 +24,13 @@ fn bindgen_test_layout_Derived() { impl Clone for Derived { fn clone(&self) -> Self { *self } } -impl Default for Derived { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[repr(C)] #[derive(Debug, Default)] pub struct BaseWithDestructor { pub _address: u8, } #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Default)] pub struct DerivedFromBaseWithDestructor { pub _address: u8, } @@ -47,9 +44,6 @@ fn bindgen_test_layout_DerivedFromBaseWithDestructor() { "Alignment of " , stringify ! ( DerivedFromBaseWithDestructor ) )); } -impl Default for DerivedFromBaseWithDestructor { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[test] fn __bindgen_test_layout_Base_open0_Derived_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( diff --git a/tests/expectations/tests/issue-573-layout-test-failures.rs b/tests/expectations/tests/issue-573-layout-test-failures.rs index df5d9fc96c..50ea61e075 100644 --- a/tests/expectations/tests/issue-573-layout-test-failures.rs +++ b/tests/expectations/tests/issue-573-layout-test-failures.rs @@ -5,15 +5,12 @@ #[repr(C)] -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Default, Copy, Clone)] pub struct Outer { pub i: u8, } -impl Default for Outer { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct AutoIdVector { pub ar: Outer, } @@ -32,9 +29,6 @@ fn bindgen_test_layout_AutoIdVector() { impl Clone for AutoIdVector { fn clone(&self) -> Self { *self } } -impl Default for AutoIdVector { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[test] fn __bindgen_test_layout_Outer_open0_int_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( diff --git a/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs b/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs index 3c8f87c3a6..dd987b764d 100644 --- a/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs +++ b/tests/expectations/tests/issue-574-assertion-failure-in-codegen.rs @@ -10,7 +10,7 @@ pub struct a { pub _address: u8, } #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct _bindgen_ty_1 { pub ar: a, } @@ -29,9 +29,6 @@ fn bindgen_test_layout__bindgen_ty_1() { impl Clone for _bindgen_ty_1 { fn clone(&self) -> Self { *self } } -impl Default for _bindgen_ty_1 { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} extern "C" { #[link_name = "AutoIdVector"] pub static mut AutoIdVector: _bindgen_ty_1; diff --git a/tests/expectations/tests/issue-674-1.rs b/tests/expectations/tests/issue-674-1.rs index 01257c2377..31fe3c5396 100644 --- a/tests/expectations/tests/issue-674-1.rs +++ b/tests/expectations/tests/issue-674-1.rs @@ -12,14 +12,11 @@ pub mod root { #[allow(unused_imports)] use self::super::super::root; #[repr(C)] - #[derive(Debug, Copy, Clone)] + #[derive(Debug, Default, Copy, Clone)] pub struct Maybe { pub _address: u8, } pub type Maybe_ValueType = T; - impl Default for Maybe { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } - } } #[repr(C)] #[derive(Debug, Default, Copy)] diff --git a/tests/expectations/tests/issue-674-2.rs b/tests/expectations/tests/issue-674-2.rs index 5e9ca485ea..cfbef26944 100644 --- a/tests/expectations/tests/issue-674-2.rs +++ b/tests/expectations/tests/issue-674-2.rs @@ -12,14 +12,11 @@ pub mod root { #[allow(unused_imports)] use self::super::super::root; #[repr(C)] - #[derive(Debug, Copy, Clone)] + #[derive(Debug, Default, Copy, Clone)] pub struct Rooted { pub _address: u8, } pub type Rooted_ElementType = T; - impl Default for Rooted { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } - } } #[repr(C)] #[derive(Debug, Default, Copy)] diff --git a/tests/expectations/tests/issue-674-3.rs b/tests/expectations/tests/issue-674-3.rs index 6e915a18af..71f794c387 100644 --- a/tests/expectations/tests/issue-674-3.rs +++ b/tests/expectations/tests/issue-674-3.rs @@ -9,14 +9,11 @@ pub mod root { #[allow(unused_imports)] use self::super::root; #[repr(C)] - #[derive(Debug, Copy, Clone)] + #[derive(Debug, Default, Copy, Clone)] pub struct nsRefPtrHashtable { pub _address: u8, } pub type nsRefPtrHashtable_UserDataType = *mut PtrType; - impl Default for nsRefPtrHashtable { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } - } #[repr(C)] #[derive(Debug, Default, Copy)] pub struct a { diff --git a/tests/expectations/tests/no-recursive-whitelisting.rs b/tests/expectations/tests/no-recursive-whitelisting.rs index e2aba54369..abd092bcc3 100644 --- a/tests/expectations/tests/no-recursive-whitelisting.rs +++ b/tests/expectations/tests/no-recursive-whitelisting.rs @@ -6,7 +6,7 @@ pub enum Bar {} #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct Foo { pub baz: *mut Bar, } @@ -25,6 +25,3 @@ fn bindgen_test_layout_Foo() { impl Clone for Foo { fn clone(&self) -> Self { *self } } -impl Default for Foo { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} diff --git a/tests/expectations/tests/replace_use.rs b/tests/expectations/tests/replace_use.rs index 3998d5b38e..2569f7ac3a 100644 --- a/tests/expectations/tests/replace_use.rs +++ b/tests/expectations/tests/replace_use.rs @@ -11,7 +11,7 @@ pub struct nsTArray { pub y: ::std::os::raw::c_uint, } #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct Test { pub a: nsTArray, } @@ -30,9 +30,6 @@ fn bindgen_test_layout_Test() { impl Clone for Test { fn clone(&self) -> Self { *self } } -impl Default for Test { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[test] fn __bindgen_test_layout_nsTArray_open0_long_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 4usize , concat ! ( diff --git a/tests/expectations/tests/typeref.rs b/tests/expectations/tests/typeref.rs index 92f40cc864..53119f090e 100644 --- a/tests/expectations/tests/typeref.rs +++ b/tests/expectations/tests/typeref.rs @@ -29,7 +29,7 @@ impl ::std::fmt::Debug for __BindgenUnionField { } } #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Default, Copy)] pub struct nsFoo { pub mBar: mozilla_StyleShapeSource, } @@ -48,9 +48,6 @@ fn bindgen_test_layout_nsFoo() { impl Clone for nsFoo { fn clone(&self) -> Self { *self } } -impl Default for nsFoo { - fn default() -> Self { unsafe { ::std::mem::zeroed() } } -} #[repr(C)] #[derive(Debug, Default, Copy)] pub struct mozilla_FragmentOrURL {