• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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