diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/analysis/derive_partial_eq.rs | 128 | ||||
-rw-r--r-- | src/ir/analysis/mod.rs | 2 | ||||
-rw-r--r-- | src/ir/context.rs | 4 | ||||
-rw-r--r-- | src/ir/derive.rs | 26 | ||||
-rw-r--r-- | src/ir/function.rs | 6 | ||||
-rw-r--r-- | src/ir/layout.rs | 6 |
6 files changed, 93 insertions, 79 deletions
diff --git a/src/ir/analysis/derive_partial_eq.rs b/src/ir/analysis/derive_partial_eq.rs index 96689601..876477ab 100644 --- a/src/ir/analysis/derive_partial_eq.rs +++ b/src/ir/analysis/derive_partial_eq.rs @@ -5,7 +5,7 @@ use ir::comp::CompKind; use ir::comp::Field; use ir::comp::FieldMethods; use ir::context::{BindgenContext, ItemId}; -use ir::derive::CanTriviallyDerivePartialEq; +use ir::derive::CanTriviallyDerivePartialEqOrPartialOrd; use ir::item::IsOpaque; use ir::traversal::EdgeKind; use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; @@ -13,48 +13,48 @@ use ir::ty::TypeKind; use std::collections::HashMap; use std::collections::HashSet; -/// An analysis that finds for each IR item whether partialeq cannot be derived. +/// An analysis that finds for each IR item whether partialeq or partialord cannot be derived. /// -/// We use the monotone constraint function `cannot_derive_partial_eq`, defined as +/// 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 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. +/// * 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 a type alias, a templated alias or an indirection to another type, -/// partialeq cannot be derived if the type T refers to cannot be derived partialeq. -/// * If T is a compound type, partialeq cannot be derived if any of its base member -/// or field cannot be derived partialeq. -/// * If T is a pointer, T cannot be derived partialeq if T is a function pointer -/// and the function signature cannot be derived partialeq. +/// 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. /// * If T is an instantiation of an abstract template definition, T cannot be -/// derived partialeq if any of the template arguments or template definition -/// cannot derive partialeq. +/// derived partialeq or partialord if any of the template arguments or template definition +/// cannot derive partialeq or partialord. #[derive(Debug, Clone)] -pub struct CannotDerivePartialEq<'ctx> { +pub struct CannotDerivePartialEqOrPartialOrd<'ctx> { ctx: &'ctx BindgenContext, // The incremental result of this analysis's computation. Everything in this - // set cannot derive partialeq. - cannot_derive_partialeq: HashSet<ItemId>, + // set cannot derive partialeq or partialord. + cannot_derive_partialeq_or_partialord: HashSet<ItemId>, // Dependencies saying that if a key ItemId has been inserted into the - // `cannot_derive_partialeq` set, then each of the ids in Vec<ItemId> need to be - // considered again. + // `cannot_derive_partialeq_or_partialord` 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 partialeq or not. + // can derive partialeq or partialord. dependencies: HashMap<ItemId, Vec<ItemId>>, } -impl<'ctx> CannotDerivePartialEq<'ctx> { +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 not. + // partialeq or partialord. EdgeKind::BaseMember | EdgeKind::Field | EdgeKind::TypeReference | @@ -75,9 +75,9 @@ impl<'ctx> CannotDerivePartialEq<'ctx> { } fn insert(&mut self, id: ItemId) -> ConstrainResult { - trace!("inserting {:?} into the cannot_derive_partialeq set", id); + trace!("inserting {:?} into the cannot_derive_partialeq_or_partialord set", id); - let was_not_already_in_set = self.cannot_derive_partialeq.insert(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 \ @@ -89,20 +89,20 @@ impl<'ctx> CannotDerivePartialEq<'ctx> { } } -impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { +impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { type Node = ItemId; type Extra = &'ctx BindgenContext; type Output = HashSet<ItemId>; fn new( ctx: &'ctx BindgenContext, - ) -> CannotDerivePartialEq<'ctx> { - let cannot_derive_partialeq = HashSet::new(); + ) -> CannotDerivePartialEqOrPartialOrd<'ctx> { + let cannot_derive_partialeq_or_partialord = HashSet::new(); let dependencies = generate_dependencies(ctx, Self::consider_edge); - CannotDerivePartialEq { + CannotDerivePartialEqOrPartialOrd { ctx, - cannot_derive_partialeq, + cannot_derive_partialeq_or_partialord, dependencies, } } @@ -114,8 +114,8 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { fn constrain(&mut self, id: ItemId) -> ConstrainResult { trace!("constrain: {:?}", id); - if self.cannot_derive_partialeq.contains(&id) { - trace!(" already know it cannot derive PartialEq"); + if self.cannot_derive_partialeq_or_partialord.contains(&id) { + trace!(" already know it cannot derive PartialEq or PartialOrd"); return ConstrainResult::Same; } @@ -131,15 +131,15 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { 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() + 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 for the layout"); + trace!(" we can trivially derive PartialEq or PartialOrd for the layout"); ConstrainResult::Same } else { - trace!(" we cannot derive PartialEq for the layout"); + trace!(" we cannot derive PartialEq or PartialOrd for the layout"); self.insert(id) }; } @@ -172,24 +172,24 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { TypeKind::ObjCInterface(..) | TypeKind::ObjCId | TypeKind::ObjCSel => { - trace!(" simple type that can always derive PartialEq"); + trace!(" simple type that can always derive PartialEq or PartialOrd"); ConstrainResult::Same } TypeKind::Array(t, len) => { - if self.cannot_derive_partialeq.contains(&t) { + if self.cannot_derive_partialeq_or_partialord.contains(&t) { trace!( - " arrays of T for which we cannot derive PartialEq \ - also cannot derive PartialEq" + " arrays of T for which we cannot derive PartialEq or PartialOrd \ + also cannot derive PartialEq or PartialOrd" ); return self.insert(id); } if len <= RUST_DERIVE_IN_ARRAY_LIMIT { - trace!(" array is small enough to derive PartialEq"); + trace!(" array is small enough to derive PartialEq or PartialOrd"); ConstrainResult::Same } else { - trace!(" array is too large to derive PartialEq"); + trace!(" array is too large to derive PartialEq or PartialOrd"); self.insert(id) } } @@ -198,9 +198,9 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'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() { + if !sig.can_trivially_derive_partialeq_or_partialord() { trace!( - " function pointer that can't trivially derive PartialEq" + " function pointer that can't trivially derive PartialEq or PartialOrd" ); return self.insert(id); } @@ -210,29 +210,29 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { } TypeKind::Function(ref sig) => { - if !sig.can_trivially_derive_partialeq() { + if !sig.can_trivially_derive_partialeq_or_partialord() { trace!( - " function that can't trivially derive PartialEq" + " function that can't trivially derive PartialEq or PartialOrd" ); return self.insert(id); } - trace!(" function can derive PartialEq"); + trace!(" function can derive PartialEq or PartialOrd"); ConstrainResult::Same } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.cannot_derive_partialeq.contains(&t) { + if self.cannot_derive_partialeq_or_partialord.contains(&t) { trace!( " aliases and type refs to T which cannot derive \ - PartialEq also cannot derive PartialEq" + PartialEq or PartialOrd also cannot derive PartialEq or PartialOrd" ); self.insert(id) } else { trace!( " aliases and type refs to T which can derive \ - PartialEq can also derive PartialEq" + PartialEq or PartialOrd can also derive PartialEq or PartialOrd" ); ConstrainResult::Same } @@ -246,20 +246,20 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { if info.kind() == CompKind::Union { if self.ctx.options().rust_features().untagged_union() { - trace!(" cannot derive PartialEq for Rust unions"); + trace!(" cannot derive PartialEq or PartialOrd for Rust unions"); return self.insert(id); } if ty.layout(self.ctx).map_or(true, |l| { - l.opaque().can_trivially_derive_partialeq() + l.opaque().can_trivially_derive_partialeq_or_partialord() }) { trace!( - " union layout can trivially derive PartialEq" + " union layout can trivially derive PartialEq or PartialOrd" ); return ConstrainResult::Same; } else { - trace!(" union layout cannot derive PartialEq"); + trace!(" union layout cannot derive PartialEq or PartialOrd"); return self.insert(id); } } @@ -267,11 +267,11 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { let bases_cannot_derive = info.base_members().iter().any(|base| { !self.ctx.whitelisted_items().contains(&base.ty) || - self.cannot_derive_partialeq.contains(&base.ty) + self.cannot_derive_partialeq_or_partialord.contains(&base.ty) }); if bases_cannot_derive { trace!( - " base members cannot derive PartialEq, so we can't \ + " base members cannot derive PartialEq or PartialOrd, so we can't \ either" ); return self.insert(id); @@ -283,7 +283,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { !self.ctx.whitelisted_items().contains( &data.ty(), ) || - self.cannot_derive_partialeq.contains( + self.cannot_derive_partialeq_or_partialord.contains( &data.ty(), ) } @@ -292,7 +292,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { !self.ctx.whitelisted_items().contains( &b.ty(), ) || - self.cannot_derive_partialeq.contains( + self.cannot_derive_partialeq_or_partialord.contains( &b.ty(), ) }) @@ -300,7 +300,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { }); if fields_cannot_derive { trace!( - " fields cannot derive PartialEq, so we can't either" + " fields cannot derive PartialEq or PartialOrd, so we can't either" ); return self.insert(id); } @@ -312,11 +312,11 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { TypeKind::TemplateInstantiation(ref template) => { let args_cannot_derive = template.template_arguments().iter().any(|arg| { - self.cannot_derive_partialeq.contains(&arg) + self.cannot_derive_partialeq_or_partialord.contains(&arg) }); if args_cannot_derive { trace!( - " template args cannot derive PartialEq, so \ + " template args cannot derive PartialEq or PartialOrd, so \ insantiation can't either" ); return self.insert(id); @@ -326,18 +326,18 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { !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.contains( + let def_cannot_derive = self.cannot_derive_partialeq_or_partialord.contains( &template.template_definition(), ); if def_cannot_derive { trace!( - " template definition cannot derive PartialEq, so \ + " template definition cannot derive PartialEq or PartialOrd, so \ insantiation can't either" ); return self.insert(id); } - trace!(" template instantiation can derive PartialEq"); + trace!(" template instantiation can derive PartialEq or PartialOrd"); ConstrainResult::Same } @@ -362,8 +362,8 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEq<'ctx> { } } -impl<'ctx> From<CannotDerivePartialEq<'ctx>> for HashSet<ItemId> { - fn from(analysis: CannotDerivePartialEq<'ctx>) -> Self { - analysis.cannot_derive_partialeq +impl<'ctx> From<CannotDerivePartialEqOrPartialOrd<'ctx>> for HashSet<ItemId> { + 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 ab19cb4f..9caf789f 100644 --- a/src/ir/analysis/mod.rs +++ b/src/ir/analysis/mod.rs @@ -56,7 +56,7 @@ pub use self::has_type_param_in_array::HasTypeParameterInArray; mod derive_hash; pub use self::derive_hash::CannotDeriveHash; mod derive_partial_eq; -pub use self::derive_partial_eq::CannotDerivePartialEq; +pub use self::derive_partial_eq::CannotDerivePartialEqOrPartialOrd; mod has_float; pub use self::has_float::HasFloat; diff --git a/src/ir/context.rs b/src/ir/context.rs index 031b0329..d512b2c8 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -2,7 +2,7 @@ use super::analysis::{CannotDeriveCopy, CannotDeriveDebug, CannotDeriveDefault, CannotDeriveHash, - CannotDerivePartialEq, HasTypeParameterInArray, + CannotDerivePartialEqOrPartialOrd, HasTypeParameterInArray, HasVtableAnalysis, HasDestructorAnalysis, UsedTemplateParameters, HasFloat, analyze}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, @@ -2129,7 +2129,7 @@ impl BindgenContext { let _t = self.timer("compute_cannot_derive_partialeq_or_eq"); assert!(self.cannot_derive_partialeq.is_none()); if self.options.derive_partialeq || self.options.derive_eq { - self.cannot_derive_partialeq = Some(analyze::<CannotDerivePartialEq>(self)); + self.cannot_derive_partialeq = Some(analyze::<CannotDerivePartialEqOrPartialOrd>(self)); } } diff --git a/src/ir/derive.rs b/src/ir/derive.rs index 909d5e42..0d6b2875 100644 --- a/src/ir/derive.rs +++ b/src/ir/derive.rs @@ -79,7 +79,7 @@ pub trait CanDeriveHash { fn can_derive_hash(&self, ctx: &BindgenContext) -> bool; } -/// A trait that encapsulates the logic for whether or not we can derive `PartialEq` +/// 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 @@ -87,11 +87,24 @@ pub trait CanDeriveHash { /// derive default or not, because of the limit rust has on 32 items as max in the /// array. pub trait CanDerivePartialEq { - /// Return `true` if `Default` can be derived for this thing, `false` + /// 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 default or not, because of the limit rust has on 32 items as max in the +/// array. +pub trait CanDerivePartialOrd { + /// Return `true` if `PartialOrd` can be derived for this thing, `false` + /// otherwise. + fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool; +} + /// A trait that encapsulates the logic for whether or not we can derive `Eq` /// for a given thing. /// @@ -118,12 +131,13 @@ pub trait CanTriviallyDeriveHash { fn can_trivially_derive_hash(&self) -> bool; } -/// A trait that encapsulates the logic for whether or not we can derive `PartialEq`. +/// 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. -pub trait CanTriviallyDerivePartialEq { - /// Return `true` if `PartialEq` can be derived for this thing, `false` +pub trait CanTriviallyDerivePartialEqOrPartialOrd { + /// Return `true` if `PartialEq` or `PartialOrd` can be derived for this thing, `false` /// otherwise. - fn can_trivially_derive_partialeq(&self) -> bool; + fn can_trivially_derive_partialeq_or_partialord(&self) -> bool; } diff --git a/src/ir/function.rs b/src/ir/function.rs index b08824af..f37f0f3c 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, - CanTriviallyDerivePartialEq}; + CanTriviallyDerivePartialEqOrPartialOrd}; use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult}; use quote; use std::io; @@ -556,8 +556,8 @@ impl CanTriviallyDeriveHash for FunctionSig { } } -impl CanTriviallyDerivePartialEq for FunctionSig { - fn can_trivially_derive_partialeq(&self) -> bool { +impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig { + fn can_trivially_derive_partialeq_or_partialord(&self) -> bool { if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT { return false; } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index 4b0b1769..298fe54a 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -2,7 +2,7 @@ use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug, CanTriviallyDeriveDefault, CanTriviallyDeriveHash, - CanTriviallyDerivePartialEq}; + CanTriviallyDerivePartialEqOrPartialOrd}; use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind}; use clang; use std::{cmp, mem}; @@ -138,8 +138,8 @@ impl CanTriviallyDeriveHash for Opaque { } } -impl CanTriviallyDerivePartialEq for Opaque { - fn can_trivially_derive_partialeq(&self) -> bool { +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 }) |