summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen/impl_debug.rs (renamed from src/codegen/derive_debug.rs)0
-rw-r--r--src/codegen/mod.rs39
-rw-r--r--src/ir/analysis/derive_partial_eq_or_partial_ord.rs89
-rw-r--r--src/ir/comp.rs32
-rw-r--r--src/ir/context.rs25
-rw-r--r--src/ir/derive.rs121
-rw-r--r--src/ir/function.rs54
-rw-r--r--src/ir/layout.rs29
-rw-r--r--src/ir/objc.rs14
-rw-r--r--src/lib.rs22
10 files changed, 211 insertions, 214 deletions
diff --git a/src/codegen/derive_debug.rs b/src/codegen/impl_debug.rs
index 7ef108da..7ef108da 100644
--- a/src/codegen/derive_debug.rs
+++ b/src/codegen/impl_debug.rs
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 49187125..895422b0 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1,4 +1,4 @@
-mod derive_debug;
+mod impl_debug;
mod error;
mod helpers;
pub mod struct_layout;
@@ -865,24 +865,6 @@ impl CodeGenerator for TemplateInstantiation {
}
}
-/// Generates an infinite number of anonymous field names.
-struct AnonFieldNames(usize);
-
-impl Default for AnonFieldNames {
- fn default() -> AnonFieldNames {
- AnonFieldNames(0)
- }
-}
-
-impl Iterator for AnonFieldNames {
- type Item = String;
-
- fn next(&mut self) -> Option<String> {
- self.0 += 1;
- Some(format!("__bindgen_anon_{}", self.0))
- }
-}
-
/// Trait for implementing the code generation of a struct or union field.
trait FieldCodegen<'a> {
type Extra;
@@ -894,7 +876,6 @@ trait FieldCodegen<'a> {
codegen_depth: usize,
accessor_kind: FieldAccessorKind,
parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
result: &mut CodegenResult,
struct_layout: &mut StructLayoutTracker,
fields: &mut F,
@@ -915,7 +896,6 @@ impl<'a> FieldCodegen<'a> for Field {
codegen_depth: usize,
accessor_kind: FieldAccessorKind,
parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
result: &mut CodegenResult,
struct_layout: &mut StructLayoutTracker,
fields: &mut F,
@@ -933,7 +913,6 @@ impl<'a> FieldCodegen<'a> for Field {
codegen_depth,
accessor_kind,
parent,
- anon_field_names,
result,
struct_layout,
fields,
@@ -948,7 +927,6 @@ impl<'a> FieldCodegen<'a> for Field {
codegen_depth,
accessor_kind,
parent,
- anon_field_names,
result,
struct_layout,
fields,
@@ -970,7 +948,6 @@ impl<'a> FieldCodegen<'a> for FieldData {
codegen_depth: usize,
accessor_kind: FieldAccessorKind,
parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
result: &mut CodegenResult,
struct_layout: &mut StructLayoutTracker,
fields: &mut F,
@@ -1030,7 +1007,7 @@ impl<'a> FieldCodegen<'a> for FieldData {
let field_name =
self.name()
.map(|name| ctx.rust_mangle(name).into_owned())
- .unwrap_or_else(|| anon_field_names.next().unwrap());
+ .expect("Each field should have a name in codegen!");
let field_ident = ctx.rust_ident_raw(field_name.as_str());
if !parent.is_union() {
@@ -1164,7 +1141,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
codegen_depth: usize,
accessor_kind: FieldAccessorKind,
parent: &CompInfo,
- anon_field_names: &mut AnonFieldNames,
result: &mut CodegenResult,
struct_layout: &mut StructLayoutTracker,
fields: &mut F,
@@ -1213,7 +1189,6 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
codegen_depth,
accessor_kind,
parent,
- anon_field_names,
result,
struct_layout,
fields,
@@ -1321,7 +1296,6 @@ impl<'a> FieldCodegen<'a> for Bitfield {
_codegen_depth: usize,
_accessor_kind: FieldAccessorKind,
parent: &CompInfo,
- _anon_field_names: &mut AnonFieldNames,
_result: &mut CodegenResult,
_struct_layout: &mut StructLayoutTracker,
_fields: &mut F,
@@ -1595,7 +1569,6 @@ impl CodeGenerator for CompInfo {
let mut methods = vec![];
if !is_opaque {
- let mut anon_field_names = AnonFieldNames::default();
let codegen_depth = item.codegen_depth(ctx);
let fields_should_be_private =
item.annotations().private_fields().unwrap_or(false);
@@ -1609,7 +1582,6 @@ impl CodeGenerator for CompInfo {
codegen_depth,
struct_accessor_kind,
self,
- &mut anon_field_names,
result,
&mut struct_layout,
&mut fields,
@@ -1910,7 +1882,7 @@ impl CodeGenerator for CompInfo {
}
if needs_debug_impl {
- let impl_ = derive_debug::gen_debug_impl(
+ let impl_ = impl_debug::gen_debug_impl(
ctx,
self.fields(),
item,
@@ -2454,7 +2426,10 @@ impl CodeGenerator for Enum {
let repr =
self.repr()
.and_then(|repr| repr.try_to_rust_ty_or_opaque(ctx, &()).ok())
- .unwrap_or_else(|| helpers::ast_ty::raw_type(ctx, repr_name));
+ .unwrap_or_else(|| {
+ let repr_name = ctx.rust_ident_raw(repr_name);
+ quote! { #repr_name }
+ });
let mut builder = EnumBuilder::new(
&name,
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 1c3ab059..f34a256a 100644
--- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
+++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs
@@ -1,4 +1,5 @@
-//! Determining which types for which we can emit `#[derive(PartialEq)]`.
+//! Determining which types for which we cannot emit `#[derive(PartialEq,
+//! PartialOrd)]`.
use super::{ConstrainResult, MonotoneFramework, generate_dependencies};
use ir::comp::CompKind;
@@ -13,31 +14,39 @@ use ir::ty::TypeKind;
use std::collections::HashMap;
use std::collections::HashSet;
-/// An analysis that finds for each IR item whether partialeq or partialord cannot be derived.
+/// An analysis that finds for each IR item whether `PartialEq`/`PartialOrd`
+/// cannot be derived.
///
-/// We use the monotone constraint function `cannot_derive_partialeq_or_partialord`, defined as
-/// follows:
+/// We use the monotone constraint function
+/// `cannot_derive_partialeq_or_partialord`, 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, 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 or partialord.
+///
+/// * 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 a type alias, a templated alias or an indirection to another type,
-/// partialeq or partialord cannot be derived if the type T refers to cannot be derived partialeq or partialord.
-/// * If T is a compound type, partialeq or partialord cannot be derived if any of its base member
-/// or field cannot be derived partialeq or partialord.
-/// * If T is a pointer, T cannot be derived partialeq or partialord if T is a function pointer
-/// and the function signature cannot be derived partialeq or partialord.
+/// `PartialEq`/`PartialOrd` cannot be derived if the type T refers to cannot be
+/// derived `PartialEq`/`PartialOrd`.
+///
+/// * If T is a compound type, `PartialEq`/`PartialOrd` cannot be derived if any
+/// of its base member or field cannot be derived `PartialEq`/`PartialOrd`.
+///
+/// * If T is a pointer, T cannot be derived `PartialEq`/`PartialOrd` if T is a
+/// function pointer and the function signature cannot be derived
+/// `PartialEq`/`PartialOrd`.
+///
/// * If T is an instantiation of an abstract template definition, T cannot be
-/// derived partialeq or partialord if any of the template arguments or template definition
-/// cannot derive partialeq or partialord.
+/// derived `PartialEq`/`PartialOrd` if any of the template arguments or
+/// template definition cannot derive `PartialEq`/`PartialOrd`.
#[derive(Debug, Clone)]
pub struct CannotDerivePartialEqOrPartialOrd<'ctx> {
ctx: &'ctx BindgenContext,
// The incremental result of this analysis's computation. Everything in this
- // set cannot derive partialeq or partialord.
+ // set cannot derive `PartialEq`/`PartialOrd`.
cannot_derive_partialeq_or_partialord: HashSet<ItemId>,
// Dependencies saying that if a key ItemId has been inserted into the
@@ -46,7 +55,7 @@ pub struct CannotDerivePartialEqOrPartialOrd<'ctx> {
//
// 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 partialeq or partialord.
+ // can derive `PartialEq`/`PartialOrd`.
dependencies: HashMap<ItemId, Vec<ItemId>>,
}
@@ -54,7 +63,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
fn consider_edge(kind: EdgeKind) -> bool {
match kind {
// These are the only edges that can affect whether a type can derive
- // partialeq or partialord.
+ // `PartialEq`/`PartialOrd`.
EdgeKind::BaseMember |
EdgeKind::Field |
EdgeKind::TypeReference |
@@ -115,7 +124,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
trace!("constrain: {:?}", id);
if self.cannot_derive_partialeq_or_partialord.contains(&id) {
- trace!(" already know it cannot derive PartialEq or PartialOrd");
+ trace!(" already know it cannot derive `PartialEq`/`PartialOrd`");
return ConstrainResult::Same;
}
@@ -140,10 +149,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
return if layout_can_derive &&
!(ty.is_union() &&
self.ctx.options().rust_features().untagged_union()) {
- trace!(" we can trivially derive PartialEq or PartialOrd for the layout");
+ trace!(" we can trivially derive `PartialEq`/`PartialOrd` for the layout");
ConstrainResult::Same
} else {
- trace!(" we cannot derive PartialEq or PartialOrd for the layout");
+ trace!(" we cannot derive `PartialEq`/`PartialOrd` for the layout");
self.insert(id)
};
}
@@ -176,24 +185,24 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
TypeKind::ObjCSel => {
- trace!(" simple type that can always derive PartialEq or PartialOrd");
+ trace!(" simple type that can always derive `PartialEq`/`PartialOrd`");
ConstrainResult::Same
}
TypeKind::Array(t, len) => {
if self.cannot_derive_partialeq_or_partialord.contains(&t) {
trace!(
- " arrays of T for which we cannot derive PartialEq or PartialOrd \
- also cannot derive PartialEq or PartialOrd"
+ " arrays of T for which we cannot derive `PartialEq`/`PartialOrd` \
+ also cannot derive `PartialEq`/`PartialOrd`"
);
return self.insert(id);
}
if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
- trace!(" array is small enough to derive PartialEq or PartialOrd");
+ trace!(" array is small enough to derive `PartialEq`/`PartialOrd`");
ConstrainResult::Same
} else {
- trace!(" array is too large to derive PartialEq or PartialOrd");
+ trace!(" array is too large to derive `PartialEq`/`PartialOrd`");
self.insert(id)
}
}
@@ -204,7 +213,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
if let TypeKind::Function(ref sig) = *inner_type.kind() {
if !sig.can_trivially_derive_partialeq_or_partialord() {
trace!(
- " function pointer that can't trivially derive PartialEq or PartialOrd"
+ " function pointer that can't trivially derive `PartialEq`/`PartialOrd`"
);
return self.insert(id);
}
@@ -216,11 +225,11 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::Function(ref sig) => {
if !sig.can_trivially_derive_partialeq_or_partialord() {
trace!(
- " function that can't trivially derive PartialEq or PartialOrd"
+ " function that can't trivially derive `PartialEq`/`PartialOrd`"
);
return self.insert(id);
}
- trace!(" function can derive PartialEq or PartialOrd");
+ trace!(" function can derive `PartialEq`/`PartialOrd`");
ConstrainResult::Same
}
@@ -230,13 +239,13 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
if self.cannot_derive_partialeq_or_partialord.contains(&t) {
trace!(
" aliases and type refs to T which cannot derive \
- PartialEq or PartialOrd also cannot derive PartialEq or PartialOrd"
+ `PartialEq`/`PartialOrd` also cannot derive `PartialEq`/`PartialOrd`"
);
self.insert(id)
} else {
trace!(
" aliases and type refs to T which can derive \
- PartialEq or PartialOrd can also derive PartialEq or PartialOrd"
+ `PartialEq`/`PartialOrd` can also derive `PartialEq`/`PartialOrd`"
);
ConstrainResult::Same
}
@@ -250,7 +259,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
- trace!(" cannot derive PartialEq or PartialOrd for Rust unions");
+ trace!(" cannot derive `PartialEq`/`PartialOrd` for Rust unions");
return self.insert(id);
}
@@ -259,11 +268,11 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
})
{
trace!(
- " union layout can trivially derive PartialEq or PartialOrd"
+ " union layout can trivially derive `PartialEq`/`PartialOrd`"
);
return ConstrainResult::Same;
} else {
- trace!(" union layout cannot derive PartialEq or PartialOrd");
+ trace!(" union layout cannot derive `PartialEq`/`PartialOrd`");
return self.insert(id);
}
}
@@ -275,7 +284,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
});
if bases_cannot_derive {
trace!(
- " base members cannot derive PartialEq or PartialOrd, so we can't \
+ " base members cannot derive `PartialEq`/`PartialOrd`, so we can't \
either"
);
return self.insert(id);
@@ -312,7 +321,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
});
if fields_cannot_derive {
trace!(
- " fields cannot derive PartialEq or PartialOrd, so we can't either"
+ " fields cannot derive `PartialEq`/`PartialOrd`, so we can't either"
);
return self.insert(id);
}
@@ -328,8 +337,8 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
});
if args_cannot_derive {
trace!(
- " template args cannot derive PartialEq or PartialOrd, so \
- insantiation can't either"
+ " template args cannot derive `PartialEq`/`PartialOrd`, so \
+ insantiation can't either"
);
return self.insert(id);
}
@@ -343,13 +352,13 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
);
if def_cannot_derive {
trace!(
- " template definition cannot derive PartialEq or PartialOrd, so \
- insantiation can't either"
+ " template definition cannot derive `PartialEq`/`PartialOrd`, so \
+ insantiation can't either"
);
return self.insert(id);
}
- trace!(" template instantiation can derive PartialEq or PartialOrd");
+ trace!(" template instantiation can derive `PartialEq`/`PartialOrd`");
ConstrainResult::Same
}
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 4c57a86b..fc17ab8f 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -666,6 +666,33 @@ impl CompFields {
CompFields::AfterComputingBitfieldUnits(fields_and_units),
);
}
+
+ fn deanonymize_fields(&mut self) {
+ let fields = match *self {
+ CompFields::AfterComputingBitfieldUnits(ref mut fields) => {
+ fields
+ }
+ CompFields::BeforeComputingBitfieldUnits(_) => {
+ panic!("Not yet computed bitfield units.");
+ }
+ };
+
+ let mut anon_field_counter = 0;
+ for field in fields.iter_mut() {
+ let field_data = match *field {
+ Field::DataMember(ref mut fd) => fd,
+ Field::Bitfields(_) => continue,
+ };
+
+ if let Some(_) = field_data.name {
+ continue;
+ }
+
+ anon_field_counter += 1;
+ let name = format!("__bindgen_anon_{}", anon_field_counter);
+ field_data.name = Some(name);
+ }
+ }
}
impl Trace for CompFields {
@@ -1351,6 +1378,11 @@ impl CompInfo {
self.fields.compute_bitfield_units(ctx);
}
+ /// Assign for each anonymous field a generated name.
+ pub fn deanonymize_fields(&mut self) {
+ self.fields.deanonymize_fields();
+ }
+
/// Returns whether the current union can be represented as a Rust `union`
///
/// Requirements:
diff --git a/src/ir/context.rs b/src/ir/context.rs
index b2c53aac..b540d152 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -239,8 +239,9 @@ pub struct BindgenContext {
/// The set of (`ItemId`s of) types that can't derive hash.
///
- /// This is populated when we enter codegen by `compute_can_derive_partialeq`
- /// and is always `None` before that and `Some` after.
+ /// 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>>,
/// The set of (`ItemId's of`) types that has vtable.
@@ -799,6 +800,18 @@ impl BindgenContext {
}
}
+ /// Assign a new generated name for each anonymous field.
+ fn deanonymize_fields(&mut self) {
+ let _t = self.timer("deanonymize_fields");
+ let comp_types = self.items
+ .values_mut()
+ .filter_map(|item| item.kind_mut().as_type_mut())
+ .filter_map(Type::as_comp_mut);
+ for comp_info in comp_types {
+ comp_info.deanonymize_fields();
+ }
+ }
+
/// Iterate over all items and replace any item that has been named in a
/// `replaces="SomeType"` annotation with the replacement type.
fn process_replacements(&mut self) {
@@ -940,6 +953,8 @@ impl BindgenContext {
self.compute_bitfield_units();
self.process_replacements();
}
+
+ self.deanonymize_fields();
// And assert once again, because resolving type refs and processing
// replacements both mutate the IR graph.
@@ -2149,8 +2164,7 @@ impl BindgenContext {
}
}
- /// Look up whether the item with `id` can
- /// derive partialeq or partialord.
+ /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`.
pub fn lookup_item_id_can_derive_partialeq_or_partialord(&self, id: ItemId) -> bool {
assert!(
self.in_codegen_phase(),
@@ -2162,8 +2176,7 @@ impl BindgenContext {
!self.cannot_derive_partialeq_or_partialord.as_ref().unwrap().contains(&id)
}
- /// Look up whether the item with `id` can
- /// derive copy or not.
+ /// Look up whether the item with `id` can derive `Copy` or not.
pub fn lookup_item_id_can_derive_copy(&self, id: ItemId) -> bool {
assert!(
self.in_codegen_phase(),
diff --git a/src/ir/derive.rs b/src/ir/derive.rs
index f518152a..cafbd3b1 100644
--- a/src/ir/derive.rs
+++ b/src/ir/derive.rs
@@ -1,27 +1,32 @@
//! Traits for determining whether we can derive traits for a thing or not.
+//!
+//! These traits tend to come in pairs:
+//!
+//! 1. A "trivial" version, whose implementations aren't allowed to recursively
+//! look at other types or the results of fix point analyses.
+//!
+//! 2. A "normal" version, whose implementations simply query the results of a
+//! fix point analysis.
+//!
+//! The former is used by the analyses when creating the results queried by the
+//! second.
use super::context::BindgenContext;
/// A trait that encapsulates the logic for whether or not we can derive `Debug`
/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// to be a recursive method that checks whether all the proper members can
-/// derive debug or not, because of the limit rust has on 32 items as max in the
-/// array.
pub trait CanDeriveDebug {
/// Return `true` if `Debug` can be derived for this thing, `false`
/// otherwise.
fn can_derive_debug(&self, ctx: &BindgenContext) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `Debug`.
-/// The difference between this trait and the CanDeriveDebug 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.
+/// A trait that encapsulates the logic for whether or not we can trivially
+/// derive `Debug` without looking at any other types or the results of a fix
+/// point analysis. This is a helper trait for the fix point analysis.
pub trait CanTriviallyDeriveDebug {
- /// Return `true` if `Debug` can be derived for this thing, `false`
- /// otherwise.
+ /// Return `true` if `Debug` can trivially be derived for this thing,
+ /// `false` otherwise.
fn can_trivially_derive_debug(&self) -> bool;
}
@@ -33,72 +38,50 @@ pub trait CanDeriveCopy<'a> {
fn can_derive_copy(&'a self, ctx: &'a BindgenContext) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `Copy`.
-/// The difference between this trait and the CanDeriveCopy 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.
+/// A trait that encapsulates the logic for whether or not we can trivially
+/// derive `Copy` without looking at any other types or results of fix point
+/// analsyses. This is a helper trait for fix point analysis.
pub trait CanTriviallyDeriveCopy {
- /// Return `true` if `Copy` can be derived for this thing, `false`
+ /// Return `true` if `Copy` can be trivially derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_copy(&self) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `Default`
-/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// 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.
+/// A trait that encapsulates the logic for whether or not we can derive
+/// `Default` for a given thing.
pub trait CanDeriveDefault {
/// Return `true` if `Default` can be derived for this thing, `false`
/// otherwise.
fn can_derive_default(&self, 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.
+/// A trait that encapsulates the logic for whether or not we can trivially
+/// derive `Default` without looking at any other types or results of fix point
+/// analyses. This is a helper trait for the fix point analysis.
pub trait CanTriviallyDeriveDefault {
- /// Return `true` if `Default` can be derived for this thing, `false`
+ /// Return `true` if `Default` can trivially derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_default(&self) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can derive `Hash`
/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// 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 CanDeriveHash {
- /// Return `true` if `Default` can be derived for this thing, `false`
+ /// Return `true` if `Hash` can be derived for this thing, `false`
/// otherwise.
fn can_derive_hash(&self, ctx: &BindgenContext) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`
-/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// 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.
+/// A trait that encapsulates the logic for whether or not we can derive
+/// `PartialEq` for a given thing.
pub trait CanDerivePartialEq {
/// Return `true` if `PartialEq` can be derived for this thing, `false`
/// otherwise.
fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `PartialOrd`
-/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// to be a recursive method that checks whether all the proper members can
-/// derive partial ord or not, because of the limit rust has on 32 items as max in the
-/// array.
+/// A trait that encapsulates the logic for whether or not we can derive
+/// `PartialOrd` for a given thing.
pub trait CanDerivePartialOrd {
/// Return `true` if `PartialOrd` can be derived for this thing, `false`
/// otherwise.
@@ -107,50 +90,32 @@ pub trait CanDerivePartialOrd {
/// A trait that encapsulates the logic for whether or not we can derive `Eq`
/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// to be a recursive method that checks whether all the proper members can
-/// derive eq or not, because of the limit rust has on 32 items as max in the
-/// array.
pub trait CanDeriveEq {
-
- /// Return `true` if `Eq` can be derived for this thing, `false`
- /// otherwise.
- fn can_derive_eq(&self,
- ctx: &BindgenContext)
- -> bool;
+ /// Return `true` if `Eq` can be derived for this thing, `false` otherwise.
+ fn can_derive_eq(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can derive `Ord`
/// for a given thing.
-///
-/// This should ideally be a no-op that just returns `true`, but instead needs
-/// to be a recursive method that checks whether all the proper members can
-/// derive ord or not, because of the limit rust has on 32 items as max in the
-/// array.
pub trait CanDeriveOrd {
- /// Return `true` if `Ord` can be derived for this thing, `false`
- /// otherwise.
+ /// Return `true` if `Ord` can be derived for this thing, `false` otherwise.
fn can_derive_ord(&self, ctx: &BindgenContext) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `Hash`.
-/// The difference between this trait and the CanDeriveHash 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.
+/// A trait that encapsulates the logic for whether or not we can derive `Hash`
+/// without looking at any other types or the results of any fix point
+/// analyses. This is a helper trait for the fix point analysis.
pub trait CanTriviallyDeriveHash {
- /// Return `true` if `Hash` can be derived for this thing, `false`
+ /// Return `true` if `Hash` can trivially be derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_hash(&self) -> bool;
}
-/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`
-/// or `PartialOrd`.
-/// The difference between this trait and the CanDerivePartialEq 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.
+/// A trait that encapsulates the logic for whether or not we can trivially
+/// derive `PartialEq` or `PartialOrd` without looking at any other types or
+/// results of fix point analyses. This is a helper for the fix point analysis.
pub trait CanTriviallyDerivePartialEqOrPartialOrd {
- /// Return `true` if `PartialEq` or `PartialOrd` can be derived for this thing, `false`
- /// otherwise.
+ /// Return `true` if `PartialEq` or `PartialOrd` can trivially be derived
+ /// for this thing, `false` otherwise.
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool;
}
diff --git a/src/ir/function.rs b/src/ir/function.rs
index f37f0f3c..402a0230 100644
--- a/src/ir/function.rs
+++ b/src/ir/function.rs
@@ -437,6 +437,26 @@ impl FunctionSig {
// variadic functions without an initial argument.
self.is_variadic && !self.argument_types.is_empty()
}
+
+ /// Are function pointers with this signature able to derive Rust traits?
+ /// Rust only supports deriving traits for function pointers with a limited
+ /// number of parameters and a couple ABIs.
+ ///
+ /// For more details, see:
+ ///
+ /// * https://github.com/rust-lang-nursery/rust-bindgen/issues/547,
+ /// * https://github.com/rust-lang/rust/issues/38848,
+ /// * and https://github.com/rust-lang/rust/issues/40158
+ pub fn function_pointers_can_derive(&self) -> bool {
+ if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
+ return false;
+ }
+
+ match self.abi {
+ Abi::C | Abi::Unknown(..) => true,
+ _ => false,
+ }
+ }
}
impl ClangSubItemParser for Function {
@@ -523,48 +543,20 @@ impl Trace for FunctionSig {
}
}
-// Function pointers follow special rules, see:
-//
-// https://github.com/rust-lang-nursery/rust-bindgen/issues/547,
-// https://github.com/rust-lang/rust/issues/38848,
-// and https://github.com/rust-lang/rust/issues/40158
-//
-// Note that copy is always derived, so we don't need to implement it.
impl CanTriviallyDeriveDebug for FunctionSig {
fn can_trivially_derive_debug(&self) -> bool {
- if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
- return false;
- }
-
- match self.abi {
- Abi::C | Abi::Unknown(..) => true,
- _ => false,
- }
+ self.function_pointers_can_derive()
}
}
impl CanTriviallyDeriveHash for FunctionSig {
fn can_trivially_derive_hash(&self) -> bool {
- if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
- return false;
- }
-
- match self.abi {
- Abi::C | Abi::Unknown(..) => true,
- _ => false,
- }
+ self.function_pointers_can_derive()
}
}
impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig {
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
- if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
- return false;
- }
-
- match self.abi {
- Abi::C | Abi::Unknown(..) => true,
- _ => false,
- }
+ self.function_pointers_can_derive()
}
}
diff --git a/src/ir/layout.rs b/src/ir/layout.rs
index 298fe54a..2df15ef2 100644
--- a/src/ir/layout.rs
+++ b/src/ir/layout.rs
@@ -104,44 +104,43 @@ impl Opaque {
None
}
}
-}
-impl CanTriviallyDeriveDebug for Opaque {
- fn can_trivially_derive_debug(&self) -> bool {
+ /// Return `true` if this opaque layout's array size will fit within the
+ /// maximum number of array elements that Rust allows deriving traits
+ /// with. Return `false` otherwise.
+ pub fn array_size_within_derive_limit(&self) -> bool {
self.array_size().map_or(false, |size| {
size <= RUST_DERIVE_IN_ARRAY_LIMIT
})
}
}
+impl CanTriviallyDeriveDebug for Opaque {
+ fn can_trivially_derive_debug(&self) -> bool {
+ self.array_size_within_derive_limit()
+ }
+}
+
impl CanTriviallyDeriveDefault for Opaque {
fn can_trivially_derive_default(&self) -> bool {
- self.array_size().map_or(false, |size| {
- size <= RUST_DERIVE_IN_ARRAY_LIMIT
- })
+ self.array_size_within_derive_limit()
}
}
impl CanTriviallyDeriveCopy for Opaque {
fn can_trivially_derive_copy(&self) -> bool {
- self.array_size().map_or(false, |size| {
- size <= RUST_DERIVE_IN_ARRAY_LIMIT
- })
+ self.array_size_within_derive_limit()
}
}
impl CanTriviallyDeriveHash for Opaque {
fn can_trivially_derive_hash(&self) -> bool {
- self.array_size().map_or(false, |size| {
- size <= RUST_DERIVE_IN_ARRAY_LIMIT
- })
+ self.array_size_within_derive_limit()
}
}
impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
fn can_trivially_derive_partialeq_or_partialord(&self) -> bool {
- self.array_size().map_or(false, |size| {
- size <= RUST_DERIVE_IN_ARRAY_LIMIT
- })
+ self.array_size_within_derive_limit()
}
}
diff --git a/src/ir/objc.rs b/src/ir/objc.rs
index cabbd389..0f72c399 100644
--- a/src/ir/objc.rs
+++ b/src/ir/objc.rs
@@ -236,13 +236,21 @@ impl ObjCMethod {
);
}
+ // Get arguments without type signatures to pass to `msg_send!`
+ let mut args_without_types = vec![];
+ for arg in args.iter() {
+ let name_and_sig: Vec<&str> = arg.as_str().split(' ').collect();
+ let name = name_and_sig[0];
+ args_without_types.push(quote::Ident::new(name))
+ };
+
let args = split_name
.into_iter()
- .zip(args.iter())
- .map(|(arg, ty)| quote! { #arg : #ty });
+ .zip(args_without_types)
+ .map(|(arg, arg_val)| quote! { #arg : #arg_val });
quote! {
- #( #args ),*
+ #( #args )*
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 1170f9b0..9e54ddc9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -247,7 +247,7 @@ impl Builder {
output_vector.push("--no-derive-debug".into());
}
- if !self.options.impl_debug {
+ if self.options.impl_debug {
output_vector.push("--impl-debug".into());
}
@@ -857,8 +857,9 @@ impl Builder {
}
/// Set whether `PartialEq` should be derived by default.
- /// If we don't compute partialeq, we also cannot compute
- /// eq. Set the derive_eq to `false` when doit is `false`.
+ ///
+ /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
+ /// `Eq` is also disabled when `doit` is `false`.
pub fn derive_partialeq(mut self, doit: bool) -> Self {
self.options.derive_partialeq = doit;
if !doit {
@@ -868,16 +869,19 @@ impl Builder {
}
/// Set whether `Eq` should be derived by default.
- /// We can't compute Eq without computing PartialEq, so
- /// we set the same option to derive_partialeq.
+ ///
+ /// We can't derive `Eq` without also deriving `PartialEq`, so we also
+ /// enable deriving `PartialEq` when `doit` is `true`.
pub fn derive_eq(mut self, doit: bool) -> Self {
self.options.derive_eq = doit;
- self.options.derive_partialeq = doit;
+ if doit {
+ self.options.derive_partialeq = doit;
+ }
self
}
- /// Set whether or not to time bindgen phases, and print
- /// information to stderr.
+ /// Set whether or not to time bindgen phases, and print information to
+ /// stderr.
pub fn time_phases(mut self, doit: bool) -> Self {
self.options.time_phases = doit;
self
@@ -1686,7 +1690,7 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> {
for d in context.translation_unit().diags().iter() {
let msg = d.format();
let is_err = d.severity() >= CXDiagnostic_Error;
- println!("{}, err: {}", msg, is_err);
+ eprintln!("{}, err: {}", msg, is_err);
any_error |= is_err;
}