diff options
-rw-r--r-- | src/ir/analysis/derive_partial_eq_or_partial_ord.rs | 89 | ||||
-rw-r--r-- | src/ir/context.rs | 11 | ||||
-rw-r--r-- | src/ir/derive.rs | 16 | ||||
-rw-r--r-- | src/lib.rs | 18 |
4 files changed, 73 insertions, 61 deletions
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 876477ab..f90f1111 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; } @@ -136,10 +145,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) }; } @@ -172,24 +181,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) } } @@ -200,7 +209,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); } @@ -212,11 +221,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 } @@ -226,13 +235,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 } @@ -246,7 +255,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); } @@ -255,11 +264,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); } } @@ -271,7 +280,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); @@ -300,7 +309,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); } @@ -316,8 +325,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); } @@ -331,13 +340,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/context.rs b/src/ir/context.rs index 799c2e7d..7340d308 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. @@ -2148,8 +2149,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(), @@ -2161,8 +2161,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..7b5aa316 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 @@ -144,13 +144,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` -/// 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 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 CanTriviallyDerivePartialEqOrPartialOrd { - /// Return `true` if `PartialEq` or `PartialOrd` can be derived for this thing, `false` - /// otherwise. + /// Return `true` if `PartialEq` or `PartialOrd` can be derived for this + /// thing, `false` otherwise. fn can_trivially_derive_partialeq_or_partialord(&self) -> bool; } @@ -843,8 +843,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 { @@ -854,16 +855,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 |