summaryrefslogtreecommitdiffstats
path: root/third_party/rust/bindgen/ir/derive.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/bindgen/ir/derive.rs')
-rw-r--r--third_party/rust/bindgen/ir/derive.rs135
1 files changed, 135 insertions, 0 deletions
diff --git a/third_party/rust/bindgen/ir/derive.rs b/third_party/rust/bindgen/ir/derive.rs
new file mode 100644
index 0000000000..594ce2ab8f
--- /dev/null
+++ b/third_party/rust/bindgen/ir/derive.rs
@@ -0,0 +1,135 @@
+//! 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 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 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 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 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 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 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 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 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 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)
+ }
+}