diff --git a/rust/codegen_traits.rs b/rust/codegen_traits.rs index ad8dd64a87..3cd94df6dd 100644 --- a/rust/codegen_traits.rs +++ b/rust/codegen_traits.rs @@ -7,6 +7,7 @@ //! Traits that are implemeted by codegen types. +use crate::__internal::SealedInternal; use crate::{MutProxied, MutProxy, ViewProxy}; use create::Parse; use read::Serialize; @@ -14,7 +15,8 @@ use std::fmt::Debug; use write::{Clear, ClearAndParse}; /// A trait that all generated owned message types implement. -pub trait Message: MutProxied +pub trait Message: SealedInternal + + MutProxied // Create traits: + Parse + Default // Read traits: @@ -28,7 +30,8 @@ pub trait Message: MutProxied {} /// A trait that all generated message views implement. -pub trait MessageView<'msg>: ViewProxy<'msg, Proxied = Self::Message> +pub trait MessageView<'msg>: SealedInternal + + ViewProxy<'msg, Proxied = Self::Message> // Read traits: + Debug + Serialize // Thread safety: @@ -41,8 +44,8 @@ pub trait MessageView<'msg>: ViewProxy<'msg, Proxied = Self::Message> } /// A trait that all generated message muts implement. -pub trait MessageMut<'msg>: - MutProxy<'msg, MutProxied = Self::Message> +pub trait MessageMut<'msg>: SealedInternal + + MutProxy<'msg, MutProxied = Self::Message> // Read traits: + Debug + Serialize // Write traits: @@ -60,7 +63,8 @@ pub trait MessageMut<'msg>: /// Operations related to constructing a message. Only owned messages implement /// these traits. pub(crate) mod create { - pub trait Parse: Sized { + use super::SealedInternal; + pub trait Parse: SealedInternal + Sized { fn parse(serialized: &[u8]) -> Result; } } @@ -69,7 +73,9 @@ pub(crate) mod create { /// have a `&self` receiver on an owned message). Owned messages, views, and /// muts all implement these traits. pub(crate) mod read { - pub trait Serialize { + use super::SealedInternal; + + pub trait Serialize: SealedInternal { fn serialize(&self) -> Result, crate::SerializeError>; } } @@ -78,12 +84,13 @@ pub(crate) mod read { /// self` receiver on an owned message). Owned messages and muts implement these /// traits. pub(crate) mod write { + use super::SealedInternal; - pub trait Clear { + pub trait Clear: SealedInternal { fn clear(&mut self); } - pub trait ClearAndParse { + pub trait ClearAndParse: SealedInternal { fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), crate::ParseError>; } } diff --git a/rust/cord.rs b/rust/cord.rs index 14c9a60991..19fdb0ba5a 100644 --- a/rust/cord.rs +++ b/rust/cord.rs @@ -5,7 +5,7 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -use crate::__internal::Private; +use crate::__internal::{Private, SealedInternal}; use crate::{ AsView, IntoProxied, IntoView, ProtoBytes, ProtoStr, ProtoString, Proxied, Proxy, View, ViewProxy, @@ -26,6 +26,10 @@ macro_rules! impl_cord_types { Owned($t), } + impl SealedInternal for [< $t Cord>] {} + + impl<'msg> SealedInternal for [< $t Cow>]<'msg> {} + impl Proxied for [< $t Cord>] { type View<'msg> = [< $t Cow>]<'msg>; } diff --git a/rust/internal.rs b/rust/internal.rs index c2bdd007c8..a2397bdbe7 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -23,3 +23,11 @@ pub use crate::__runtime::{PtrAndLen, RawMap, RawMessage, RawRepeatedField}; /// Used to protect internal-only items from being used accidentally. #[derive(Debug)] pub struct Private; + +/// A trait that is used as a subtrait of traits that we intend to be used but +/// not be implemented by users. +/// +/// This is slightly less 'sealed' than the typical sealed trait pattern would +/// permit in other crates; this trait is intended to be available to crates +/// which were generated by protoc, but not to application code. +pub trait SealedInternal {} diff --git a/rust/map.rs b/rust/map.rs index 57647d649b..ec72d9a49e 100644 --- a/rust/map.rs +++ b/rust/map.rs @@ -8,7 +8,7 @@ use crate::{ AsMut, AsView, IntoMut, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Proxied, Proxy, View, ViewProxy, - __internal::Private, + __internal::{Private, SealedInternal}, __runtime::{InnerMap, InnerMapMut, RawMap, RawMapIter}, }; use std::marker::PhantomData; @@ -72,6 +72,8 @@ unsafe impl> Sync for Map {} // it does not use thread-local data or similar. unsafe impl> Send for Map {} +impl> SealedInternal for Map {} + impl> Drop for Map { fn drop(&mut self) { // SAFETY: @@ -129,6 +131,8 @@ impl> AsMut for Map { } } +impl<'msg, K: Proxied, V: ProxiedInMapValue> SealedInternal for MapView<'msg, K, V> {} + impl<'msg, K: Proxied, V: ProxiedInMapValue> Proxy<'msg> for MapView<'msg, K, V> {} impl<'msg, K: Proxied, V: ProxiedInMapValue> AsView for MapView<'msg, K, V> { @@ -150,6 +154,8 @@ impl<'msg, K: Proxied, V: ProxiedInMapValue> IntoView<'msg> for MapView<'msg, impl<'msg, K: Proxied, V: ProxiedInMapValue> ViewProxy<'msg> for MapView<'msg, K, V> {} +impl<'msg, K: Proxied, V: ProxiedInMapValue> SealedInternal for MapMut<'msg, K, V> {} + impl<'msg, K: Proxied, V: ProxiedInMapValue> Proxy<'msg> for MapMut<'msg, K, V> {} impl<'msg, K: Proxied, V: ProxiedInMapValue> AsView for MapMut<'msg, K, V> { diff --git a/rust/primitive.rs b/rust/primitive.rs index a87f3305f0..bf5af332a9 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -4,11 +4,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +use crate::__internal::SealedInternal; use crate::{AsView, IntoView, Proxied, Proxy, ViewProxy}; macro_rules! impl_singular_primitives { ($($t:ty),*) => { $( + impl SealedInternal for $t {} + impl Proxied for $t { type View<'msg> = $t; } diff --git a/rust/proxied.rs b/rust/proxied.rs index c56b18544f..32147908b5 100644 --- a/rust/proxied.rs +++ b/rust/proxied.rs @@ -44,7 +44,7 @@ //! implemented the concept of "proxy" types. Proxy types are a reference-like //! indirection between the user and the internal memory representation. -use crate::__internal::Private; +use crate::__internal::{Private, SealedInternal}; use std::fmt::Debug; /// A type that can be accessed through a reference-like proxy. @@ -52,7 +52,7 @@ use std::fmt::Debug; /// An instance of a `Proxied` can be accessed immutably via `Proxied::View`. /// /// All Protobuf field types implement `Proxied`. -pub trait Proxied: AsView + Sized { +pub trait Proxied: SealedInternal + AsView + Sized { /// The proxy type that provides shared access to a `T`, like a `&'msg T`. /// /// Most code should use the type alias [`View`]. @@ -67,7 +67,7 @@ pub trait Proxied: AsView + Sized { /// and immutably via `MutProxied::View`. /// /// `MutProxied` is implemented by message, map and repeated field types. -pub trait MutProxied: Proxied + AsMut { +pub trait MutProxied: SealedInternal + Proxied + AsMut { /// The proxy type that provides exclusive mutable access to a `T`, like a /// `&'msg mut T`. /// @@ -95,7 +95,7 @@ pub type Mut<'msg, T> = ::Mut<'msg>; /// types. /// /// On ViewProxy this will behave as a reborrow into a shorter lifetime. -pub trait AsView { +pub trait AsView: SealedInternal { type Proxied: Proxied; /// Converts a borrow into a `View` with the lifetime of that borrow. @@ -127,7 +127,7 @@ pub trait AsView { /// /// On a ViewProxy this will behave as a reborrow into a shorter lifetime /// (semantically matching a `&'a T` into a `&'b T` where `'a: 'b`). -pub trait IntoView<'msg>: AsView { +pub trait IntoView<'msg>: SealedInternal + AsView { /// Converts into a `View` with a potentially shorter lifetime. /// /// In non-generic code we don't need to use `into_view` because the proxy @@ -162,7 +162,7 @@ pub trait IntoView<'msg>: AsView { /// implemented on both owned `Proxied` types as well as MutProxy types. /// /// On MutProxy this will behave as a reborrow into a shorter lifetime. -pub trait AsMut: AsView { +pub trait AsMut: SealedInternal + AsView { type MutProxied: MutProxied; /// Converts a borrow into a `Mut` with the lifetime of that borrow. @@ -173,7 +173,7 @@ pub trait AsMut: AsView { /// /// On a MutProxy this will behave as a reborrow into a shorter lifetime /// (semantically matching a `&mut 'a T` into a `&mut 'b T` where `'a: 'b`). -pub trait IntoMut<'msg>: AsMut { +pub trait IntoMut<'msg>: SealedInternal + AsMut { /// Converts into a `Mut` with a potentially shorter lifetime. /// /// In non-generic code we don't need to use `into_mut` because the proxy @@ -206,16 +206,19 @@ pub trait IntoMut<'msg>: AsMut { /// /// This trait is intentionally made non-object-safe to prevent a potential /// future incompatible change. -pub trait Proxy<'msg>: 'msg + IntoView<'msg> + Sync + Unpin + Sized + Debug {} +pub trait Proxy<'msg>: + SealedInternal + 'msg + IntoView<'msg> + Sync + Unpin + Sized + Debug +{ +} /// Declares conversion operations common to view proxies. -pub trait ViewProxy<'msg>: Proxy<'msg> + Send {} +pub trait ViewProxy<'msg>: SealedInternal + Proxy<'msg> + Send {} /// Declares operations common to all mut proxies. /// /// This trait is intentionally made non-object-safe to prevent a potential /// future incompatible change. -pub trait MutProxy<'msg>: Proxy<'msg> + AsMut + IntoMut<'msg> { +pub trait MutProxy<'msg>: SealedInternal + Proxy<'msg> + AsMut + IntoMut<'msg> { /// Gets an immutable view of this field. This is shorthand for `as_view`. /// /// This provides a shorter lifetime than `into_view` but can also be called @@ -265,6 +268,8 @@ mod tests { } } + impl SealedInternal for MyProxied {} + impl Proxied for MyProxied { type View<'msg> = MyProxiedView<'msg>; } @@ -292,6 +297,8 @@ mod tests { my_proxied_ref: &'msg MyProxied, } + impl<'msg> SealedInternal for MyProxiedView<'msg> {} + impl MyProxiedView<'_> { fn val(&self) -> &str { &self.my_proxied_ref.val @@ -324,6 +331,8 @@ mod tests { my_proxied_ref: &'msg mut MyProxied, } + impl<'msg> SealedInternal for MyProxiedMut<'msg> {} + impl<'msg> Proxy<'msg> for MyProxiedMut<'msg> {} impl<'msg> AsView for MyProxiedMut<'msg> { diff --git a/rust/repeated.rs b/rust/repeated.rs index 1a43dceab0..1fd5e0e364 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -17,7 +17,7 @@ use std::marker::PhantomData; use crate::{ AsMut, AsView, IntoMut, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Proxied, Proxy, View, ViewProxy, - __internal::Private, + __internal::{Private, SealedInternal}, __runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField}, }; @@ -382,6 +382,8 @@ where type View<'msg> = RepeatedView<'msg, T> where Repeated: 'msg; } +impl SealedInternal for Repeated where T: ProxiedInRepeated {} + impl AsView for Repeated where T: ProxiedInRepeated, @@ -411,6 +413,8 @@ where } } +impl<'msg, T> SealedInternal for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {} + impl<'msg, T> Proxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {} impl<'msg, T> AsView for RepeatedView<'msg, T> @@ -440,6 +444,8 @@ where impl<'msg, T> ViewProxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {} +impl<'msg, T> SealedInternal for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {} + impl<'msg, T> Proxy<'msg> for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {} impl<'msg, T> AsView for RepeatedMut<'msg, T> diff --git a/rust/string.rs b/rust/string.rs index 32421e53f3..7c758783be 100644 --- a/rust/string.rs +++ b/rust/string.rs @@ -9,7 +9,7 @@ #![allow(dead_code)] #![allow(unused)] -use crate::__internal::Private; +use crate::__internal::{Private, SealedInternal}; use crate::__runtime::{InnerProtoString, PtrAndLen, RawMessage}; use crate::{ utf8::Utf8Chunks, AsView, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Optional, Proxied, @@ -67,6 +67,8 @@ impl From<&[u8; N]> for ProtoBytes { } } +impl SealedInternal for ProtoBytes {} + impl Proxied for ProtoBytes { type View<'msg> = &'msg [u8]; } @@ -127,6 +129,8 @@ impl IntoProxied for Arc<[u8]> { } } +impl SealedInternal for &[u8] {} + impl<'msg> Proxy<'msg> for &'msg [u8] {} impl AsView for &[u8] { @@ -217,6 +221,8 @@ impl ProtoString { } } +impl SealedInternal for ProtoString {} + impl AsRef<[u8]> for ProtoString { fn as_ref(&self) -> &[u8] { self.inner.as_bytes() @@ -241,6 +247,10 @@ impl From<&[u8]> for ProtoString { } } +impl SealedInternal for &str {} + +impl SealedInternal for &ProtoStr {} + impl IntoProxied for &str { fn into_proxied(self, _private: Private) -> ProtoString { ProtoString::from(self) diff --git a/rust/upb.rs b/rust/upb.rs index b90de06d41..cc4db52bac 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -7,7 +7,7 @@ //! UPB FFI wrapper code for use by Rust Protobuf. -use crate::__internal::{Enum, Private}; +use crate::__internal::{Enum, Private, SealedInternal}; use crate::{ IntoProxied, Map, MapIter, MapMut, MapView, Mut, ProtoBytes, ProtoStr, ProtoString, Proxied, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View, @@ -64,6 +64,8 @@ impl ScratchSpace { #[doc(hidden)] pub type SerializedData = upb::OwnedArenaBox<[u8]>; +impl SealedInternal for SerializedData {} + impl IntoProxied for SerializedData { fn into_proxied(self, _private: Private) -> ProtoBytes { ProtoBytes { inner: InnerProtoString(self) } diff --git a/src/google/protobuf/compiler/rust/enum.cc b/src/google/protobuf/compiler/rust/enum.cc index 8c39cb8602..9b4a4402cf 100644 --- a/src/google/protobuf/compiler/rust/enum.cc +++ b/src/google/protobuf/compiler/rust/enum.cc @@ -395,6 +395,8 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) { } } + impl $pbi$::SealedInternal for $name$ {} + impl $pb$::Proxied for $name$ { type View<'a> = $name$; } diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 6b652f4af9..8f3cafaee1 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -1018,6 +1018,8 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { type View<'msg> = $Msg$View<'msg>; } + impl $pbi$::SealedInternal for $Msg$ {} + impl $pb$::MutProxied for $Msg$ { type Mut<'msg> = $Msg$Mut<'msg>; } @@ -1029,6 +1031,8 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { _phantom: $Phantom$<&'msg ()>, } + impl<'msg> $pbi$::SealedInternal for $Msg$View<'msg> {} + impl<'msg> $pb$::MessageView<'msg> for $Msg$View<'msg> { type Message = $Msg$; } @@ -1101,6 +1105,8 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { inner: $pbr$::MutatorMessageRef<'msg>, } + impl<'msg> $pbi$::SealedInternal for $Msg$Mut<'msg> {} + impl<'msg> $pb$::MessageMut<'msg> for $Msg$Mut<'msg> { type Message = $Msg$; }