1 //! Traits for determining whether we can derive traits for a thing or not. 2 //! 3 //! These traits tend to come in pairs: 4 //! 5 //! 1. A "trivial" version, whose implementations aren't allowed to recursively 6 //! look at other types or the results of fix point analyses. 7 //! 8 //! 2. A "normal" version, whose implementations simply query the results of a 9 //! fix point analysis. 10 //! 11 //! The former is used by the analyses when creating the results queried by the 12 //! second. 13 14 use super::context::BindgenContext; 15 16 use std::cmp; 17 use std::ops; 18 19 /// A trait that encapsulates the logic for whether or not we can derive `Debug` 20 /// for a given thing. 21 pub trait CanDeriveDebug { 22 /// Return `true` if `Debug` can be derived for this thing, `false` 23 /// otherwise. can_derive_debug(&self, ctx: &BindgenContext) -> bool24 fn can_derive_debug(&self, ctx: &BindgenContext) -> bool; 25 } 26 27 /// A trait that encapsulates the logic for whether or not we can derive `Copy` 28 /// for a given thing. 29 pub trait CanDeriveCopy { 30 /// Return `true` if `Copy` can be derived for this thing, `false` 31 /// otherwise. can_derive_copy(&self, ctx: &BindgenContext) -> bool32 fn can_derive_copy(&self, ctx: &BindgenContext) -> bool; 33 } 34 35 /// A trait that encapsulates the logic for whether or not we can derive 36 /// `Default` for a given thing. 37 pub trait CanDeriveDefault { 38 /// Return `true` if `Default` can be derived for this thing, `false` 39 /// otherwise. can_derive_default(&self, ctx: &BindgenContext) -> bool40 fn can_derive_default(&self, ctx: &BindgenContext) -> bool; 41 } 42 43 /// A trait that encapsulates the logic for whether or not we can derive `Hash` 44 /// for a given thing. 45 pub trait CanDeriveHash { 46 /// Return `true` if `Hash` can be derived for this thing, `false` 47 /// otherwise. can_derive_hash(&self, ctx: &BindgenContext) -> bool48 fn can_derive_hash(&self, ctx: &BindgenContext) -> bool; 49 } 50 51 /// A trait that encapsulates the logic for whether or not we can derive 52 /// `PartialEq` for a given thing. 53 pub trait CanDerivePartialEq { 54 /// Return `true` if `PartialEq` can be derived for this thing, `false` 55 /// otherwise. can_derive_partialeq(&self, ctx: &BindgenContext) -> bool56 fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool; 57 } 58 59 /// A trait that encapsulates the logic for whether or not we can derive 60 /// `PartialOrd` for a given thing. 61 pub trait CanDerivePartialOrd { 62 /// Return `true` if `PartialOrd` can be derived for this thing, `false` 63 /// otherwise. can_derive_partialord(&self, ctx: &BindgenContext) -> bool64 fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool; 65 } 66 67 /// A trait that encapsulates the logic for whether or not we can derive `Eq` 68 /// for a given thing. 69 pub trait CanDeriveEq { 70 /// Return `true` if `Eq` can be derived for this thing, `false` otherwise. can_derive_eq(&self, ctx: &BindgenContext) -> bool71 fn can_derive_eq(&self, ctx: &BindgenContext) -> bool; 72 } 73 74 /// A trait that encapsulates the logic for whether or not we can derive `Ord` 75 /// for a given thing. 76 pub trait CanDeriveOrd { 77 /// Return `true` if `Ord` can be derived for this thing, `false` otherwise. can_derive_ord(&self, ctx: &BindgenContext) -> bool78 fn can_derive_ord(&self, ctx: &BindgenContext) -> bool; 79 } 80 81 /// Whether it is possible or not to automatically derive trait for an item. 82 /// 83 /// ```ignore 84 /// No 85 /// ^ 86 /// | 87 /// Manually 88 /// ^ 89 /// | 90 /// Yes 91 /// ``` 92 /// 93 /// Initially we assume that we can derive trait for all types and then 94 /// update our understanding as we learn more about each type. 95 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] 96 pub enum CanDerive { 97 /// Yes, we can derive automatically. 98 Yes, 99 100 /// The only thing that stops us from automatically deriving is that 101 /// array with more than maximum number of elements is used. 102 /// 103 /// This means we probably can "manually" implement such trait. 104 Manually, 105 106 /// No, we cannot. 107 No, 108 } 109 110 impl Default for CanDerive { default() -> CanDerive111 fn default() -> CanDerive { 112 CanDerive::Yes 113 } 114 } 115 116 impl CanDerive { 117 /// Take the least upper bound of `self` and `rhs`. join(self, rhs: Self) -> Self118 pub fn join(self, rhs: Self) -> Self { 119 cmp::max(self, rhs) 120 } 121 } 122 123 impl ops::BitOr for CanDerive { 124 type Output = Self; 125 bitor(self, rhs: Self) -> Self::Output126 fn bitor(self, rhs: Self) -> Self::Output { 127 self.join(rhs) 128 } 129 } 130 131 impl ops::BitOrAssign for CanDerive { bitor_assign(&mut self, rhs: Self)132 fn bitor_assign(&mut self, rhs: Self) { 133 *self = self.join(rhs) 134 } 135 } 136