From 1a7ce6106115d0ff1c2b82a1a9a10d6603a2c2a1 Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Wed, 24 Apr 2024 06:21:54 -0700 Subject: [PATCH] Split Proxied into Proxied and MutProxied traits. Proxied is not marked as Sized yet, because ProtoStr is still dynamically sized. We will wait for clarity for the string types before marking Proxied Sized. PiperOrigin-RevId: 627707544 --- rust/map.rs | 5 ++- rust/optional.rs | 7 ++++- rust/primitive.rs | 7 ++++- rust/proto_macro.rs | 8 ++--- rust/proxied.rs | 33 ++++++++++++++------ rust/repeated.rs | 8 ++++- rust/shared.rs | 2 +- rust/string.rs | 10 ++++-- rust/vtable.rs | 6 ++-- src/google/protobuf/compiler/rust/enum.cc | 3 ++ src/google/protobuf/compiler/rust/message.cc | 3 ++ 11 files changed, 68 insertions(+), 24 deletions(-) diff --git a/rust/map.rs b/rust/map.rs index 5ce74047b6..367793668f 100644 --- a/rust/map.rs +++ b/rust/map.rs @@ -6,7 +6,7 @@ // https://developers.google.com/open-source/licenses/bsd use crate::{ - Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, + Mut, MutProxied, MutProxy, Proxied, SettableValue, View, ViewProxy, __internal::Private, __runtime::{InnerMap, InnerMapMut, RawMap, RawMapIter}, }; @@ -95,6 +95,9 @@ where impl + ?Sized> Proxied for Map { type View<'msg> = MapView<'msg, K, V> where K: 'msg, V: 'msg; +} + +impl + ?Sized> MutProxied for Map { type Mut<'msg> = MapMut<'msg, K, V> where K: 'msg, V: 'msg; } diff --git a/rust/optional.rs b/rust/optional.rs index 0268c61bfd..741f12d4f5 100644 --- a/rust/optional.rs +++ b/rust/optional.rs @@ -10,7 +10,9 @@ #![allow(unused)] use crate::__internal::Private; -use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy}; +use crate::{ + Mut, MutProxied, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, +}; use std::convert::{AsMut, AsRef}; use std::fmt::{self, Debug}; use std::panic; @@ -495,6 +497,9 @@ mod tests { impl Proxied for VtableProxied { type View<'msg> = VtableProxiedView; + } + + impl MutProxied for VtableProxied { type Mut<'msg> = VtableProxiedMut<'msg>; } diff --git a/rust/primitive.rs b/rust/primitive.rs index 7c34795c9a..f14863187b 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -10,7 +10,9 @@ use std::fmt::Debug; use crate::__internal::Private; use crate::__runtime::InnerPrimitiveMut; use crate::vtable::{PrimitiveWithRawVTable, ProxiedWithRawVTable, RawVTableOptionalMutatorData}; -use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy}; +use crate::{ + Mut, MutProxied, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, +}; /// A mutator for a primitive (numeric or enum) value of `T`. /// @@ -98,6 +100,9 @@ macro_rules! impl_singular_primitives { $( impl Proxied for $t { type View<'msg> = $t; + } + + impl MutProxied for $t { type Mut<'msg> = PrimitiveMut<'msg, $t>; } diff --git a/rust/proto_macro.rs b/rust/proto_macro.rs index d3da607664..95b14232bf 100644 --- a/rust/proto_macro.rs +++ b/rust/proto_macro.rs @@ -53,13 +53,13 @@ macro_rules! proto_internal { // nested message (@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => { { - let mut $msg: <$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); + let mut $msg: <$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); proto_internal!(@msg $msg $field : $($value)*); } }; (@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { $field:ident : $($value:tt)* }) => { { - let mut $msg: <::$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); + let mut $msg: <::$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); proto_internal!(@msg $msg $field : $($value)*); } }; @@ -77,12 +77,12 @@ macro_rules! proto_internal { // empty nested message (@msg $msg:ident $submsg:ident : $($msgtype:ident)::+ { }) => { { - let mut $msg: <$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); + let mut $msg: <$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); } }; (@msg $msg:ident $submsg:ident : ::$($msgtype:ident)::+ { }) => { { - let mut $msg: <::$($msgtype)::+ as $crate::Proxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); + let mut $msg: <::$($msgtype)::+ as $crate::MutProxied>::Mut<'_> = $crate::__internal::paste!($msg.[<$submsg _mut>]()); } }; diff --git a/rust/proxied.rs b/rust/proxied.rs index 8d9214d28e..41ddb6a743 100644 --- a/rust/proxied.rs +++ b/rust/proxied.rs @@ -51,18 +51,25 @@ use std::fmt::Debug; /// A type that can be accessed through a reference-like proxy. /// -/// An instance of a `Proxied` can be accessed -/// immutably via `Proxied::View` and mutably via `Proxied::Mut`. +/// An instance of a `Proxied` can be accessed immutably via `Proxied::View`. /// /// All Protobuf field types implement `Proxied`. pub trait Proxied { /// The proxy type that provides shared access to a `T`, like a `&'msg T`. /// /// Most code should use the type alias [`View`]. - type View<'msg>: ViewProxy<'msg, Proxied = Self> + Copy + Send + SettableValue + type View<'msg>: ViewProxy<'msg, Proxied = Self> + Copy + Send where Self: 'msg; +} +/// A type that can be be accessed through a reference-like proxy. +/// +/// An instance of a `MutProxied` can be accessed mutably via `MutProxied::Mut` +/// and immutably via `MutProxied::View`. +/// +/// `MutProxied` is implemented by message, map and repeated field types. +pub trait MutProxied: Proxied { /// The proxy type that provides exclusive mutable access to a `T`, like a /// `&'msg mut T`. /// @@ -83,7 +90,7 @@ pub type View<'msg, T> = ::View<'msg>; /// /// This is more concise than fully spelling the associated type. #[allow(dead_code)] -pub type Mut<'msg, T> = ::Mut<'msg>; +pub type Mut<'msg, T> = ::Mut<'msg>; /// Declares conversion operations common to all views. /// @@ -147,7 +154,10 @@ pub trait ViewProxy<'msg>: 'msg + Sync + Unpin + Sized + Debug { /// /// This trait is intentionally made non-object-safe to prevent a potential /// future incompatible change. -pub trait MutProxy<'msg>: ViewProxy<'msg> { +pub trait MutProxy<'msg>: ViewProxy<'msg> +where + Self::Proxied: MutProxied, +{ /// 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 @@ -211,7 +221,7 @@ pub trait MutProxy<'msg>: ViewProxy<'msg> { /// /// All scalar and message types implement `ProxiedWithPresence`, while repeated /// types don't. -pub trait ProxiedWithPresence: Proxied { +pub trait ProxiedWithPresence: MutProxied { /// The data necessary to store a present field mutator proxying `Self`. /// This is the contents of `PresentField<'msg, Self>`. type PresentMutData<'msg>: MutProxy<'msg, Proxied = Self>; @@ -233,7 +243,7 @@ pub trait ProxiedWithPresence: Proxied { /// Values that can be used to set a field of `T`. pub trait SettableValue: Sized where - T: Proxied + ?Sized, + T: MutProxied + ?Sized, { /// Consumes `self` to set the given mutator to the value of `self`. #[doc(hidden)] @@ -308,6 +318,9 @@ mod tests { impl Proxied for MyProxied { type View<'msg> = MyProxiedView<'msg>; + } + + impl MutProxied for MyProxied { type Mut<'msg> = MyProxiedMut<'msg>; } @@ -460,7 +473,7 @@ mod tests { y: &'b View<'a, T>, ) -> [View<'b, T>; 2] where - T: Proxied, + T: MutProxied, 'a: 'b, { // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `View` @@ -509,7 +522,7 @@ mod tests { fn reborrow_generic_mut_into_view<'a, 'b, T>(x: Mut<'a, T>, y: View<'b, T>) -> [View<'b, T>; 2] where - T: Proxied, + T: MutProxied, 'a: 'b, { [x.into_view(), y] @@ -529,7 +542,7 @@ mod tests { fn reborrow_generic_mut_into_mut<'a, 'b, T>(x: Mut<'a, T>, y: Mut<'b, T>) -> [Mut<'b, T>; 2] where - T: Proxied, + T: MutProxied, 'a: 'b, { // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `Mut` diff --git a/rust/repeated.rs b/rust/repeated.rs index 068dd9a5ec..7253307fcd 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -15,7 +15,7 @@ use std::iter::FusedIterator; use std::marker::PhantomData; use crate::{ - Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, + Mut, MutProxied, MutProxy, Proxied, SettableValue, View, ViewProxy, __internal::Private, __runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField}, }; @@ -314,6 +314,12 @@ where T: ProxiedInRepeated + ?Sized, { type View<'msg> = RepeatedView<'msg, T> where Repeated: 'msg; +} + +impl MutProxied for Repeated +where + T: ProxiedInRepeated + ?Sized, +{ type Mut<'msg> = RepeatedMut<'msg, T> where Repeated: 'msg; } diff --git a/rust/shared.rs b/rust/shared.rs index 531d4d4e82..79ff7e629a 100644 --- a/rust/shared.rs +++ b/rust/shared.rs @@ -28,7 +28,7 @@ pub mod __public { pub use crate::primitive::PrimitiveMut; pub use crate::proto; pub use crate::proxied::{ - Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, + Mut, MutProxied, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, }; pub use crate::repeated::{ ProxiedInRepeated, Repeated, RepeatedIter, RepeatedMut, RepeatedView, diff --git a/rust/string.rs b/rust/string.rs index a6277d4b79..9377a53514 100644 --- a/rust/string.rs +++ b/rust/string.rs @@ -15,8 +15,8 @@ use crate::__runtime::{ }; use crate::macros::impl_forwarding_settable_value; use crate::{ - AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, Proxied, ProxiedWithPresence, - SettableValue, View, ViewProxy, + AbsentField, FieldEntry, Mut, MutProxied, MutProxy, Optional, PresentField, Proxied, + ProxiedWithPresence, SettableValue, View, ViewProxy, }; use std::borrow::Cow; use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; @@ -123,6 +123,9 @@ impl AsRef<[u8]> for BytesMut<'_> { impl Proxied for [u8] { type View<'msg> = &'msg [u8]; +} + +impl MutProxied for [u8] { type Mut<'msg> = BytesMut<'msg>; } @@ -465,6 +468,9 @@ impl Ord for ProtoStr { impl Proxied for ProtoStr { type View<'msg> = &'msg ProtoStr; +} + +impl MutProxied for ProtoStr { type Mut<'msg> = ProtoStrMut<'msg>; } diff --git a/rust/vtable.rs b/rust/vtable.rs index 52a0d87bc2..fbcf4c46a2 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -11,7 +11,7 @@ use crate::__runtime::{ RawMessage, }; use crate::{ - AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, PrimitiveMut, Proxied, + AbsentField, FieldEntry, Mut, MutProxied, MutProxy, Optional, PresentField, PrimitiveMut, ProxiedWithPresence, View, ViewProxy, }; use std::fmt::{self, Debug}; @@ -23,7 +23,7 @@ use std::ptr::NonNull; /// /// This vtable should consist of `unsafe fn`s that call thunks that operate on /// `RawMessage`. The structure of this vtable is different per proxied type. -pub trait ProxiedWithRawVTable: Proxied { +pub trait ProxiedWithRawVTable: MutProxied { /// The vtable for get/set access, stored in static memory. type VTable: Debug + 'static; @@ -443,7 +443,7 @@ pub trait PrimitiveWithRawVTable: + ProxiedWithPresence + Sync + Send - + for<'msg> Proxied = Self, Mut<'msg> = PrimitiveMut<'msg, Self>> + + for<'msg> MutProxied = Self, Mut<'msg> = PrimitiveMut<'msg, Self>> { } diff --git a/src/google/protobuf/compiler/rust/enum.cc b/src/google/protobuf/compiler/rust/enum.cc index 4184ed0975..5ce270b54f 100644 --- a/src/google/protobuf/compiler/rust/enum.cc +++ b/src/google/protobuf/compiler/rust/enum.cc @@ -393,6 +393,9 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) { impl $pb$::Proxied for $name$ { type View<'a> = $name$; + } + + impl $pb$::MutProxied for $name$ { type Mut<'a> = $pb$::PrimitiveMut<'a, $name$>; } diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 6ee718fc18..5700ebb458 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -865,6 +865,9 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { impl $pb$::Proxied for $Msg$ { type View<'msg> = $Msg$View<'msg>; + } + + impl $pb$::MutProxied for $Msg$ { type Mut<'msg> = $Msg$Mut<'msg>; }