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}