summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzzhu <zzhu@mozilla.com>2017-07-26 18:25:32 -0700
committerzzhu <zzhu@mozilla.com>2017-07-27 16:46:38 -0700
commit0231a21a98f49064d6bb58734366fdd660ba69c7 (patch)
tree122f54bab45374c08e0cb74b617dae2c60ff53d6 /src
parent0fab51e501f45727169516f605de31e7e1d19a62 (diff)
can derive default analysis
Diffstat (limited to 'src')
-rw-r--r--src/codegen/mod.rs2
-rw-r--r--src/ir/analysis/derive_default.rs360
-rw-r--r--src/ir/analysis/mod.rs2
-rw-r--r--src/ir/comp.rs69
-rw-r--r--src/ir/context.rs36
-rw-r--r--src/ir/derive.rs20
-rw-r--r--src/ir/item.rs20
-rw-r--r--src/ir/layout.rs8
-rw-r--r--src/ir/ty.rs42
9 files changed, 416 insertions, 143 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 4ae0bfeb..637e3a65 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 00000000..de74177d
--- /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<ItemId>,
+
+ // Dependencies saying that if a key ItemId has been inserted into the
+ // `cannot_derive_default` set, then each of the ids in Vec<ItemId> 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<ItemId, Vec<ItemId>>,
+}
+
+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<ItemId>;
+
+ 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<ItemId> {
+ 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<F>(&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<CannotDeriveDefault<'ctx, 'gen>> for HashSet<ItemId> {
+ 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 8a00ecce..ec150ec4 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 c2e9bd8f..b3cb3ca5 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<bool>,
-
/// Used to detect if we've run in a has_destructor cycle while cycling
/// around the template arguments.
detect_has_destructor_cycle: Cell<bool>,
@@ -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<Layout>);
-
- fn can_derive_default(&self,
- ctx: &BindgenContext,
- (item, layout): (&Item, Option<Layout>))
- -> 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<Layout>);
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 6c38e8e7..d9281a23 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<HashSet<ItemId>>,
+ /// 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<HashSet<ItemId>>,
+
/// 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::<CannotDeriveDefault>(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 3334618c..5bc9cfdd 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 92954a8f..8a210e38 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 03496ad0..b0ec171a 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 1c213569..b3de1f03 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;