bindgen/ir/derive.rs
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
14use super::context::BindgenContext;
15
16use std::cmp;
17use std::ops;
18
19/// A trait that encapsulates the logic for whether or not we can derive `Debug`
20/// for a given thing.
21pub(crate) trait CanDeriveDebug {
22 /// Return `true` if `Debug` can be derived for this thing, `false`
23 /// otherwise.
24 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.
29pub(crate) trait CanDeriveCopy {
30 /// Return `true` if `Copy` can be derived for this thing, `false`
31 /// otherwise.
32 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.
37pub(crate) trait CanDeriveDefault {
38 /// Return `true` if `Default` can be derived for this thing, `false`
39 /// otherwise.
40 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.
45pub(crate) trait CanDeriveHash {
46 /// Return `true` if `Hash` can be derived for this thing, `false`
47 /// otherwise.
48 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.
53pub(crate) trait CanDerivePartialEq {
54 /// Return `true` if `PartialEq` can be derived for this thing, `false`
55 /// otherwise.
56 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.
61pub(crate) trait CanDerivePartialOrd {
62 /// Return `true` if `PartialOrd` can be derived for this thing, `false`
63 /// otherwise.
64 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.
69pub(crate) trait CanDeriveEq {
70 /// Return `true` if `Eq` can be derived for this thing, `false` otherwise.
71 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.
76pub(crate) trait CanDeriveOrd {
77 /// Return `true` if `Ord` can be derived for this thing, `false` otherwise.
78 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, Default)]
96pub enum CanDerive {
97 /// Yes, we can derive automatically.
98 #[default]
99 Yes,
100
101 /// The only thing that stops us from automatically deriving is that
102 /// array with more than maximum number of elements is used.
103 ///
104 /// This means we probably can "manually" implement such trait.
105 Manually,
106
107 /// No, we cannot.
108 No,
109}
110
111impl CanDerive {
112 /// Take the least upper bound of `self` and `rhs`.
113 pub(crate) fn join(self, rhs: Self) -> Self {
114 cmp::max(self, rhs)
115 }
116}
117
118impl ops::BitOr for CanDerive {
119 type Output = Self;
120
121 fn bitor(self, rhs: Self) -> Self::Output {
122 self.join(rhs)
123 }
124}
125
126impl ops::BitOrAssign for CanDerive {
127 fn bitor_assign(&mut self, rhs: Self) {
128 *self = self.join(rhs);
129 }
130}