//! 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; use std::cmp; use std::ops; /// A trait that encapsulates the logic for whether or not we can derive `Debug` /// for a given thing. pub(crate) 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 `Copy` /// for a given thing. pub(crate) trait CanDeriveCopy { /// Return `true` if `Copy` can be derived for this thing, `false` /// otherwise. fn can_derive_copy(&self, ctx: &BindgenContext) -> bool; } /// A trait that encapsulates the logic for whether or not we can derive /// `Default` for a given thing. pub(crate) 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 `Hash` /// for a given thing. pub(crate) trait CanDeriveHash { /// 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. pub(crate) 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. pub(crate) 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. pub(crate) trait CanDeriveEq { /// 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. pub(crate) trait CanDeriveOrd { /// Return `true` if `Ord` can be derived for this thing, `false` otherwise. fn can_derive_ord(&self, ctx: &BindgenContext) -> bool; } /// Whether it is possible or not to automatically derive trait for an item. /// /// ```ignore /// No /// ^ /// | /// Manually /// ^ /// | /// Yes /// ``` /// /// Initially we assume that we can derive trait for all types and then /// update our understanding as we learn more about each type. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum CanDerive { /// Yes, we can derive automatically. Yes, /// The only thing that stops us from automatically deriving is that /// array with more than maximum number of elements is used. /// /// This means we probably can "manually" implement such trait. Manually, /// No, we cannot. No, } impl Default for CanDerive { fn default() -> CanDerive { CanDerive::Yes } } impl CanDerive { /// Take the least upper bound of `self` and `rhs`. pub(crate) fn join(self, rhs: Self) -> Self { cmp::max(self, rhs) } } impl ops::BitOr for CanDerive { type Output = Self; fn bitor(self, rhs: Self) -> Self::Output { self.join(rhs) } } impl ops::BitOrAssign for CanDerive { fn bitor_assign(&mut self, rhs: Self) { *self = self.join(rhs) } }