From 90fb1657b994542c6fa3b05a961fa1adf4e08f8d Mon Sep 17 00:00:00 2001 From: Ernest Date: Mon, 11 Jul 2022 15:10:26 -0400 Subject: [PATCH 1/2] Implements Sealed trait, with deliberations --- src/lib.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index e048f871b8..9d1b34f876 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -653,7 +653,7 @@ pub type Result = std::result::Result; /// This trait doesn't require `num::Zero` or `num::One` because some tensor /// types (such as `bool` and `String`) don't implement them and we need to /// supply custom implementations. -pub trait TensorType: Default + Clone + Display + Debug + 'static { +pub trait TensorType: private::Sealed + Default + Clone + Display + Debug + 'static { /// Internal only; do not use outside of the tensorflow crate. /// /// Tensor representation for this type. Normally `TensorDataCRepr` for types @@ -684,6 +684,25 @@ pub trait TensorType: Default + Clone + Display + Debug + 'static { fn pack(data: &[Self], dims: &[u64]) -> Result<*mut tf::TF_Tensor>; } +mod private { + pub trait Sealed {} + + // impl Sealed for usize {} + // impl Sealed for bool {} + // impl Sealed for u8 {} + // impl Sealed for u16 {} + // impl Sealed for u32 {} + // impl Sealed for u64 {} + // impl Sealed for i8 {} + // impl Sealed for i16 {} + // impl Sealed for i32 {} + // impl Sealed for i64 {} + // impl Sealed for f32 {} + // impl Sealed for f64 {} + + impl Sealed for T{} +} + macro_rules! tensor_type { ($rust_type:ty, $tensor_type:ident, $zero:expr, $one:expr) => { impl TensorType for $rust_type { From ef0261de5a7cbcc6939b38020c766669e776d333 Mon Sep 17 00:00:00 2001 From: Ernest Date: Wed, 13 Jul 2022 10:44:07 -0400 Subject: [PATCH 2/2] Final Cleanup and Documentation --- src/lib.rs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9d1b34f876..d5025a5504 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -644,11 +644,26 @@ pub type Result = std::result::Result; //////////////////////// +/// A common implementation of the sealed supertrait programming pattern +/// (C-SEALED) +/// +/// With this, implementations of `Sealed` are guarenteed to only exist in the +/// current crate. This allows modifictation of the underyling traits in ways +/// that would ordinarily be a breaking change for traits that are not sealed. +/// +/// See https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed + +mod private { + pub trait Sealed {} + + impl Sealed for T{} +} + /// A Rust type that maps to a `DataType`. /// /// Currently, all implementors must *not* implement Drop (or transitively contain /// anything that does) and must be bit-for-bit compatible with the corresponding C -/// type. Clients must not implement this trait. +/// type. Clients cannot implement this trait. /// /// This trait doesn't require `num::Zero` or `num::One` because some tensor /// types (such as `bool` and `String`) don't implement them and we need to @@ -684,25 +699,6 @@ pub trait TensorType: private::Sealed + Default + Clone + Display + Debug + 'sta fn pack(data: &[Self], dims: &[u64]) -> Result<*mut tf::TF_Tensor>; } -mod private { - pub trait Sealed {} - - // impl Sealed for usize {} - // impl Sealed for bool {} - // impl Sealed for u8 {} - // impl Sealed for u16 {} - // impl Sealed for u32 {} - // impl Sealed for u64 {} - // impl Sealed for i8 {} - // impl Sealed for i16 {} - // impl Sealed for i32 {} - // impl Sealed for i64 {} - // impl Sealed for f32 {} - // impl Sealed for f64 {} - - impl Sealed for T{} -} - macro_rules! tensor_type { ($rust_type:ty, $tensor_type:ident, $zero:expr, $one:expr) => { impl TensorType for $rust_type {