From 0b3e8a81c92dc1db7e037d759b6cd589167f775c Mon Sep 17 00:00:00 2001 From: Jakob Buchgraber Date: Wed, 24 Apr 2024 00:24:16 -0700 Subject: [PATCH] Remove PrimitiveMut and related vtable types The last callside that used PrimitiveMut was in our enums code. This change makes it so that enums nolonger implement MutProxied and thus no longer need the PrimitiveMut type. PiperOrigin-RevId: 627632154 --- rust/BUILD | 2 +- rust/cpp.rs | 17 +-- rust/internal.rs | 5 +- rust/map.rs | 5 +- rust/optional.rs | 7 +- rust/primitive.rs | 124 +--------------- rust/proto_macro.rs | 8 +- rust/proxied.rs | 48 ++++-- rust/repeated.rs | 8 +- rust/shared.rs | 4 +- rust/string.rs | 113 ++++----------- rust/test/shared/accessors_test.rs | 19 --- rust/upb.rs | 17 +-- rust/upb/arena.rs | 14 ++ rust/vtable.rs | 137 +----------------- .../rust/accessors/singular_message.cc | 44 +++++- .../rust/accessors/singular_string.cc | 103 ++----------- src/google/protobuf/compiler/rust/enum.cc | 30 ---- src/google/protobuf/compiler/rust/message.cc | 60 ++++---- 19 files changed, 206 insertions(+), 559 deletions(-) diff --git a/rust/BUILD b/rust/BUILD index 4aa9cb028030..092cfd46dcd0 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -49,8 +49,8 @@ PROTOBUF_SHARED = [ "enum.rs", "internal.rs", "macros.rs", - "optional.rs", "primitive.rs", + "optional.rs", "proxied.rs", "repeated.rs", "shared.rs", diff --git a/rust/cpp.rs b/rust/cpp.rs index 225c97e5192b..fe726679a0fc 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -171,6 +171,13 @@ impl Deref for SerializedData { } } +// TODO: remove after IntoProxied has been implemented for bytes. +impl AsRef<[u8]> for SerializedData { + fn as_ref(&self) -> &[u8] { + self + } +} + impl Drop for SerializedData { fn drop(&mut self) { // SAFETY: `data` was allocated by the Rust global allocator with a @@ -185,15 +192,6 @@ impl fmt::Debug for SerializedData { } } -impl SettableValue<[u8]> for SerializedData { - fn set_on<'msg>(self, _private: Private, mut mutator: Mut<'msg, [u8]>) - where - [u8]: 'msg, - { - mutator.set(self.as_ref()) - } -} - /// A type to transfer an owned Rust string across the FFI boundary: /// * This struct is ABI-compatible with the equivalent C struct. /// * It owns its data but does not drop it. Immediately turn it into a @@ -240,7 +238,6 @@ pub type MessageAbsentMutData<'msg, T> = crate::vtable::RawVTableOptionalMutator pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; -pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; pub type RawMapIter = UntypedMapIterator; #[derive(Debug)] diff --git a/rust/internal.rs b/rust/internal.rs index 4a9486e91acc..742423bc1072 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -14,9 +14,8 @@ pub use paste::paste; pub use crate::r#enum::Enum; pub use crate::vtable::{ - new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveOptionalMutVTable, - PrimitiveVTable, PrimitiveWithRawVTable, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, - RawVTableMutator, RawVTableOptionalMutatorData, + new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, ProxiedWithRawOptionalVTable, + ProxiedWithRawVTable, RawVTableMutator, RawVTableOptionalMutatorData, }; pub use crate::ProtoStr; diff --git a/rust/map.rs b/rust/map.rs index 5ce74047b6aa..367793668f86 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 0268c61bfd79..741f12d4f573 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 7c34795c9a60..75665eca2b13 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -4,101 +4,13 @@ // 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 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}; - -/// A mutator for a primitive (numeric or enum) value of `T`. -/// -/// This type is `protobuf::Mut<'msg, T>`. -pub struct PrimitiveMut<'msg, T> { - inner: InnerPrimitiveMut<'msg, T>, -} - -impl<'msg, T> Debug for PrimitiveMut<'msg, T> -where - T: PrimitiveWithRawVTable, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("PrimitiveMut").field("inner", &self.inner).finish() - } -} - -impl<'msg, T> PrimitiveMut<'msg, T> { - /// # Safety - /// `inner` must be valid and non-aliased for `T` for `'msg` - #[doc(hidden)] - pub unsafe fn from_inner(_private: Private, inner: InnerPrimitiveMut<'msg, T>) -> Self { - Self { inner } - } -} - -// SAFETY: all `T` that can perform mutations don't mutate through a shared -// reference. -unsafe impl<'msg, T> Sync for PrimitiveMut<'msg, T> {} - -impl<'msg, T> PrimitiveMut<'msg, T> -where - T: PrimitiveWithRawVTable, -{ - /// Gets the current value of the field. - pub fn get(&self) -> View<'_, T> { - T::make_view(Private, self.inner) - } - - /// Sets a new value for the field. - pub fn set(&mut self, val: impl SettableValue) { - val.set_on(Private, self.as_mut()) - } - - #[doc(hidden)] - pub fn set_primitive(&mut self, _private: Private, value: T) { - // SAFETY: the raw mutator is valid for `'msg` as enforced by `Mut` - unsafe { self.inner.set(value) } - } -} - -impl<'msg, T> ViewProxy<'msg> for PrimitiveMut<'msg, T> -where - T: PrimitiveWithRawVTable, -{ - type Proxied = T; - - fn as_view(&self) -> View<'_, Self::Proxied> { - self.get() - } - - fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> { - self.get() - } -} - -impl<'msg, T> MutProxy<'msg> for PrimitiveMut<'msg, T> -where - T: PrimitiveWithRawVTable, -{ - fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { - PrimitiveMut { inner: self.inner } - } - - fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> - where - 'msg: 'shorter, - { - self - } -} +use crate::{Proxied, View, ViewProxy}; macro_rules! impl_singular_primitives { ($($t:ty),*) => { $( impl Proxied for $t { type View<'msg> = $t; - type Mut<'msg> = PrimitiveMut<'msg, $t>; } impl<'msg> ViewProxy<'msg> for $t { @@ -113,40 +25,6 @@ macro_rules! impl_singular_primitives { } } - impl SettableValue<$t> for $t { - fn set_on<'msg>(self, private: Private, mut mutator: Mut<'msg, $t>) where $t: 'msg { - mutator.set_primitive(private, self) - } - - fn set_on_absent( - self, - _private: Private, - absent_mutator: <$t as ProxiedWithPresence>::PresentMutData<'_>, - ) -> <$t as ProxiedWithPresence>::AbsentMutData<'_> - { - absent_mutator.set(Private, self) - } - } - - impl ProxiedWithPresence for $t { - type PresentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>; - type AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>; - - fn clear_present_field( - present_mutator: Self::PresentMutData<'_>, - ) -> Self::AbsentMutData<'_> { - present_mutator.clear(Private) - } - - fn set_absent_to_default( - absent_mutator: Self::AbsentMutData<'_>, - ) -> Self::PresentMutData<'_> { - absent_mutator.set_absent_to_default(Private) - } - } - - impl PrimitiveWithRawVTable for $t {} - // ProxiedInRepeated is implemented in {cpp,upb}.rs )* } diff --git a/rust/proto_macro.rs b/rust/proto_macro.rs index d3da60766468..95b14232bf0c 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 8d9214d28e4a..beef53c15d01 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. /// @@ -127,7 +134,7 @@ pub trait ViewProxy<'msg>: 'msg + Sync + Unpin + Sized + Debug { /// y: View<'b, 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` @@ -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)] @@ -285,6 +295,19 @@ where } } +/// A value to `Proxied`-value conversion that consumes the input value. +/// +/// All setter functions accept types that implement `IntoProxied`. The purpose +/// of `IntoProxied` is to allow setting arbitrary values on Protobuf fields +/// with the minimal number of copies. +/// +/// This trait must not be implemented on types outside the Protobuf codegen and +/// runtime. We expect it to change in backwards incompatible ways in the +/// future. +pub trait IntoProxied { + fn into(self, _private: Private) -> T; +} + #[cfg(test)] mod tests { use super::*; @@ -308,6 +331,9 @@ mod tests { impl Proxied for MyProxied { type View<'msg> = MyProxiedView<'msg>; + } + + impl MutProxied for MyProxied { type Mut<'msg> = MyProxiedMut<'msg>; } @@ -460,7 +486,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 +535,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 +555,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 068dd9a5eccc..7253307fcdab 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 531d4d4e8277..158b87bb4039 100644 --- a/rust/shared.rs +++ b/rust/shared.rs @@ -25,10 +25,10 @@ pub mod __public { pub use crate::r#enum::UnknownEnumValue; pub use crate::map::{Map, MapIter, MapMut, MapView, ProxiedInMapValue}; pub use crate::optional::{AbsentField, FieldEntry, Optional, PresentField}; - pub use crate::primitive::PrimitiveMut; pub use crate::proto; pub use crate::proxied::{ - Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, + IntoProxied, 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 a6277d4b79e1..e54ec44bc02d 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>; } @@ -182,53 +185,6 @@ impl<'msg> MutProxy<'msg> for BytesMut<'msg> { } } -impl SettableValue<[u8]> for &'_ [u8] { - fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, [u8]>) - where - [u8]: 'msg, - { - // SAFETY: this is a `bytes` field with no restriction on UTF-8. - unsafe { mutator.inner.set(self) } - } - - fn set_on_absent( - self, - _private: Private, - absent_mutator: <[u8] as ProxiedWithPresence>::AbsentMutData<'_>, - ) -> <[u8] as ProxiedWithPresence>::PresentMutData<'_> { - // SAFETY: this is a `bytes` field with no restriction on UTF-8. - unsafe { absent_mutator.set(self) } - } - - fn set_on_present( - self, - _private: Private, - present_mutator: <[u8] as ProxiedWithPresence>::PresentMutData<'_>, - ) { - // SAFETY: this is a `bytes` field with no restriction on UTF-8. - unsafe { - present_mutator.set(self); - } - } -} - -impl SettableValue<[u8]> for &'_ [u8; N] { - // forward to `self[..]` - impl_forwarding_settable_value!([u8], self => &self[..]); -} - -impl SettableValue<[u8]> for Vec { - // TODO: Investigate taking ownership of this when allowed by the - // runtime. - impl_forwarding_settable_value!([u8], self => &self[..]); -} - -impl SettableValue<[u8]> for Cow<'_, [u8]> { - // TODO: Investigate taking ownership of this when allowed by the - // runtime. - impl_forwarding_settable_value!([u8], self => &self[..]); -} - impl Hash for BytesMut<'_> { fn hash(&self, state: &mut H) { self.deref().hash(state) @@ -465,6 +421,9 @@ impl Ord for ProtoStr { impl Proxied for ProtoStr { type View<'msg> = &'msg ProtoStr; +} + +impl MutProxied for ProtoStr { type Mut<'msg> = ProtoStrMut<'msg>; } @@ -695,50 +654,28 @@ impl<'msg> MutProxy<'msg> for ProtoStrMut<'msg> { } } -impl SettableValue for &'_ ProtoStr { - fn set_on<'b>(self, _private: Private, mutator: Mut<'b, ProtoStr>) - where - ProtoStr: 'b, - { - // SAFETY: A `ProtoStr` has the same UTF-8 validity requirement as the runtime. - unsafe { mutator.bytes.inner.set(self.as_bytes()) } - } - - fn set_on_absent( - self, - _private: Private, - absent_mutator: ::AbsentMutData<'_>, - ) -> ::PresentMutData<'_> { - // SAFETY: A `ProtoStr` has the same UTF-8 validity requirement as the runtime. - StrPresentMutData(unsafe { absent_mutator.0.set(self.as_bytes()) }) - } - - fn set_on_present( - self, - _private: Private, - present_mutator: ::PresentMutData<'_>, - ) { - // SAFETY: A `ProtoStr` has the same UTF-8 validity requirement as the runtime. - unsafe { - present_mutator.0.set(self.as_bytes()); - } +// TODO: remove after IntoProxied has been implemented for +// ProtoStr. +impl AsRef for String { + fn as_ref(&self) -> &ProtoStr { + ProtoStr::from_str(self.as_str()) } } -impl SettableValue for &'_ str { - impl_forwarding_settable_value!(ProtoStr, self => ProtoStr::from_str(self)); -} - -impl SettableValue for String { - // TODO: Investigate taking ownership of this when allowed by the - // runtime. - impl_forwarding_settable_value!(ProtoStr, self => ProtoStr::from_str(&self)); +// TODO: remove after IntoProxied has been implemented for +// ProtoStr. +impl AsRef for &str { + fn as_ref(&self) -> &ProtoStr { + ProtoStr::from_str(self) + } } -impl SettableValue for Cow<'_, str> { - // TODO: Investigate taking ownership of this when allowed by the - // runtime. - impl_forwarding_settable_value!(ProtoStr, self => ProtoStr::from_str(&self)); +// TODO: remove after IntoProxied has been implemented for +// ProtoStr. +impl AsRef for &ProtoStr { + fn as_ref(&self) -> &ProtoStr { + self + } } impl Hash for ProtoStrMut<'_> { diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index fa11b86d0734..36caf8b00ca6 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -507,16 +507,9 @@ fn test_singular_msg_field() { assert_that!(msg.has_optional_nested_message(), eq(false)); let mut nested_msg_mut = msg.optional_nested_message_mut(); - // test reading an int inside a mut assert_that!(nested_msg_mut.bb(), eq(0)); - // Test setting an owned NestedMessage onto another message. - let mut new_nested = NestedMessage::new(); - new_nested.set_bb(7); - nested_msg_mut.set(new_nested); - assert_that!(nested_msg_mut.bb(), eq(7)); - assert_that!(msg.has_optional_nested_message(), eq(true)); } @@ -762,18 +755,6 @@ fn test_msg_oneof_default_accessors() { // TODO: Add tests covering a message-type field in a oneof. } -#[test] -fn test_set_message_from_view() { - use protobuf::MutProxy; - - let mut m1 = TestAllTypes::new(); - m1.set_optional_int32(1); - let mut m2 = TestAllTypes::new(); - m2.as_mut().set(m1.as_view()); - - assert_that!(m2.optional_int32(), eq(1i32)); -} - #[test] fn test_group() { let mut m = TestAllTypes::new(); diff --git a/rust/upb.rs b/rust/upb.rs index 5a0c07e47156..8bca74715eb7 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -97,18 +97,16 @@ impl Deref for SerializedData { } } -impl fmt::Debug for SerializedData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(self.deref(), f) +// TODO: remove after IntoProxied has been implemented for bytes. +impl AsRef<[u8]> for SerializedData { + fn as_ref(&self) -> &[u8] { + self } } -impl SettableValue<[u8]> for SerializedData { - fn set_on<'msg>(self, _private: Private, mut mutator: Mut<'msg, [u8]>) - where - [u8]: 'msg, - { - mutator.set(self.as_ref()) +impl fmt::Debug for SerializedData { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self.deref(), f) } } @@ -118,7 +116,6 @@ pub type MessageAbsentMutData<'msg, T> = crate::vtable::RawVTableOptionalMutator pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; -pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; #[derive(Debug)] pub struct MessageVTable { diff --git a/rust/upb/arena.rs b/rust/upb/arena.rs index 8610d4de5651..6e8045cefb69 100644 --- a/rust/upb/arena.rs +++ b/rust/upb/arena.rs @@ -95,6 +95,19 @@ impl Arena { // `UPB_MALLOC_ALIGN` boundary. unsafe { slice::from_raw_parts_mut(ptr.cast(), layout.size()) } } + + /// Fuse two arenas so they share the same lifetime. + pub fn fuse(&self, other: &Arena) { + // SAFETY: `self.raw()` and `other.raw()` are both valid UPB arenas. + let success = unsafe { upb_Arena_Fuse(self.raw(), other.raw()) }; + if !success { + // Fusing can fail if any of the arenas has an initial block i.e. the arena is + // backed by a preallocated chunk of memory that it doesn't own and thus cannot + // lifetime extend. This function panics because this is typically not a + // recoverable error but a logic bug in a program. + panic!("Could not fuse two UPB arenas."); + } + } } impl Default for Arena { @@ -117,6 +130,7 @@ extern "C" { fn upb_Arena_New() -> Option; fn upb_Arena_Free(arena: RawArena); fn upb_Arena_Malloc(arena: RawArena, size: usize) -> *mut u8; + fn upb_Arena_Fuse(arena1: RawArena, arena2: RawArena) -> bool; } #[cfg(test)] diff --git a/rust/vtable.rs b/rust/vtable.rs index 52a0d87bc22d..27f14db92236 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -7,11 +7,10 @@ use crate::__internal::Private; use crate::__runtime::{ - copy_bytes_in_arena_if_needed_by_runtime, InnerPrimitiveMut, MutatorMessageRef, PtrAndLen, - RawMessage, + copy_bytes_in_arena_if_needed_by_runtime, MutatorMessageRef, PtrAndLen, RawMessage, }; use crate::{ - AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, PrimitiveMut, Proxied, + AbsentField, FieldEntry, Mut, MutProxied, MutProxy, Optional, PresentField, ProxiedWithPresence, View, ViewProxy, }; use std::fmt::{self, Debug}; @@ -23,7 +22,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; @@ -281,47 +280,6 @@ impl ProxiedWithRawOptionalVTable for [u8] { } } -/// A generic thunk vtable for mutating a present primitive field. -#[doc(hidden)] -#[derive(Debug)] -pub struct PrimitiveVTable { - pub(crate) setter: unsafe extern "C" fn(msg: RawMessage, val: T), - pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> T, -} - -#[doc(hidden)] -#[derive(Debug)] -/// A generic thunk vtable for mutating an `optional` primitive field. -pub struct PrimitiveOptionalMutVTable { - pub(crate) base: PrimitiveVTable, - pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage), - pub(crate) default: T, -} - -impl PrimitiveVTable { - #[doc(hidden)] - pub const fn new( - _private: Private, - getter: unsafe extern "C" fn(msg: RawMessage) -> T, - setter: unsafe extern "C" fn(msg: RawMessage, val: T), - ) -> Self { - Self { getter, setter } - } -} - -impl PrimitiveOptionalMutVTable { - #[doc(hidden)] - pub const fn new( - _private: Private, - getter: unsafe extern "C" fn(msg: RawMessage) -> T, - setter: unsafe extern "C" fn(msg: RawMessage, val: T), - clearer: unsafe extern "C" fn(msg: RawMessage), - default: T, - ) -> Self { - Self { base: PrimitiveVTable { getter, setter }, clearer, default } - } -} - /// A generic thunk vtable for mutating a present `bytes` or `string` field. #[doc(hidden)] #[derive(Debug)] @@ -425,92 +383,3 @@ impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> { self } } - -/// Primitive types using a vtable for message access that are trivial to copy -/// and have a `'static` lifetime. -/// -/// Implementing this trait automatically implements `ProxiedWithRawVTable`, -/// `ProxiedWithRawOptionalVTable`, and get/set/clear methods on -/// `RawVTableMutator` and `RawVTableOptionalMutatorData` that use the vtable. -/// -/// It doesn't implement `Proxied`, `ViewProxy`, `SettableValue` or -/// `ProxiedWithPresence` for `Self` to avoid future conflicting blanket impls -/// on those traits. -pub trait PrimitiveWithRawVTable: - Copy - + Debug - + 'static - + ProxiedWithPresence - + Sync - + Send - + for<'msg> Proxied = Self, Mut<'msg> = PrimitiveMut<'msg, Self>> -{ -} - -impl ProxiedWithRawVTable for T { - type VTable = PrimitiveVTable; - - fn make_view(_private: Private, mut_inner: InnerPrimitiveMut<'_, Self>) -> Self { - mut_inner.get() - } - - fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> PrimitiveMut<'_, Self> { - // SAFETY: `inner` is valid for the necessary lifetime and `T` as promised by - // the caller of `InnerPrimitiveMut::new`. - unsafe { PrimitiveMut::from_inner(Private, inner) } - } -} - -impl ProxiedWithRawOptionalVTable for T { - type OptionalVTable = PrimitiveOptionalMutVTable; - - fn upcast_vtable( - _private: Private, - optional_vtable: &'static Self::OptionalVTable, - ) -> &'static Self::VTable { - &optional_vtable.base - } -} - -impl RawVTableMutator<'_, T> { - pub(crate) fn get(self) -> T { - // SAFETY: - // - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by - // the caller of `new`. - unsafe { (self.vtable().getter)(self.msg_ref.msg()) } - } - - /// # Safety - /// - `msg_ref` must be valid for the lifetime of `RawVTableMutator`. - pub(crate) unsafe fn set(self, val: T) { - // SAFETY: - // - `msg_ref` is valid for the lifetime of `RawVTableMutator` as promised by - // the caller of `new`. - unsafe { (self.vtable().setter)(self.msg_ref.msg(), val) } - } -} - -impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> { - pub fn set_absent_to_default(self, private: Private) -> Self { - // SAFETY: - // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as - // promised by the caller of `new`. - self.set(private, self.optional_vtable().default) - } - - pub fn set(self, _private: Private, val: T) -> Self { - // SAFETY: - // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as - // promised by the caller of `new`. - unsafe { (self.optional_vtable().base.setter)(self.msg_ref.msg(), val) } - self - } - - pub fn clear(self, _private: Private) -> Self { - // SAFETY: - // - `msg_ref` is valid for the lifetime of `RawVTableOptionalMutatorData` as - // promised by the caller of `new`. - unsafe { (self.optional_vtable().clearer)(self.msg_ref.msg()) } - self - } -} diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc index 8f3ea9bfe0d5..628c209355c6 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_message.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -33,6 +33,7 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, {"hazzer_thunk", ThunkName(ctx, field, "has")}, + {"setter_thunk", ThunkName(ctx, field, "set")}, { "getter_body", [&] { @@ -94,7 +95,7 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field, unsafe { let has = self.has_$raw_field_name$(); $pbi$::new_vtable_field_entry($pbi$::Private, - self.as_mutator_message_ref(), + self.as_mutator_message_ref($pbi$::Private), &VTABLE, has) } @@ -111,14 +112,39 @@ void SingularMessage::InMsgImpl(Context& ctx, const FieldDescriptor& field, } )rs"); }}, + {"setter_body", + [&] { + if (accessor_case == AccessorCase::VIEW) return; + if (ctx.is_upb()) { + ctx.Emit({}, R"rs( + self.as_mutator_message_ref($pbi$::Private) + .arena($pbi$::Private) + .fuse(msg.as_mutator_message_ref($pbi$::Private).arena($pbi$::Private)); + + unsafe { + $setter_thunk$(self.as_mutator_message_ref($pbi$::Private).msg(), + msg.as_mutator_message_ref($pbi$::Private).msg()); + } + )rs"); + } else { + ctx.Emit({}, R"rs( + unsafe { + $setter_thunk$(self.as_mutator_message_ref($pbi$::Private).msg(), + msg.as_mutator_message_ref($pbi$::Private).msg()); + } + )rs"); + } + }}, {"setter", [&] { if (accessor_case == AccessorCase::VIEW) return; ctx.Emit(R"rs( - pub fn set_$raw_field_name$(&mut self, val: impl $pb$::SettableValue<$msg_type$>) { - //~ TODO: Optimize this to not go through the - //~ FieldEntry. - self.$raw_field_name$_entry().set(val); + pub fn set_$raw_field_name$(&mut self, + val: impl $pb$::IntoProxied<$msg_type$>) { + let val = val.into($pbi$::Private); + let mut msg = std::mem::ManuallyDrop::new(val); + + $setter_body$ } )rs"); }}, @@ -156,6 +182,7 @@ void SingularMessage::InExternC(Context& ctx, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, {"hazzer_thunk", ThunkName(ctx, field, "has")}, + {"setter_thunk", ThunkName(ctx, field, "set")}, {"getter_mut", [&] { if (ctx.is_cpp()) { @@ -187,12 +214,16 @@ void SingularMessage::InExternC(Context& ctx, $getter_mut$ fn $clearer_thunk$(raw_msg: $pbr$::RawMessage); fn $hazzer_thunk$(raw_msg: $pbr$::RawMessage) -> bool; + fn $setter_thunk$(raw_msg: $pbr$::RawMessage, + field_msg: $pbr$::RawMessage); )rs"); } void SingularMessage::InThunkCc(Context& ctx, const FieldDescriptor& field) const { ctx.Emit({{"QualifiedMsg", cpp::QualifiedClassName(field.containing_type())}, + {"FieldMsg", cpp::QualifiedClassName(field.message_type())}, + {"setter_thunk", ThunkName(ctx, field, "set")}, {"getter_thunk", ThunkName(ctx, field, "get")}, {"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}, {"clearer_thunk", ThunkName(ctx, field, "clear")}, @@ -207,6 +238,9 @@ void SingularMessage::InThunkCc(Context& ctx, } void $clearer_thunk$($QualifiedMsg$* msg) { msg->clear_$field$(); } bool $hazzer_thunk$($QualifiedMsg$* msg) { return msg->has_$field$(); } + void $setter_thunk$($QualifiedMsg$* msg, $FieldMsg$* sub_msg) { + msg->set_allocated_$field$(sub_msg); + } )cc"); } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_string.cc b/src/google/protobuf/compiler/rust/accessors/singular_string.cc index afb3592e75eb..e0917b02b7de 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_string.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_string.cc @@ -9,7 +9,6 @@ #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/accessors/accessor_case.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" -#include "google/protobuf/compiler/rust/accessors/helpers.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/compiler/rust/naming.h" #include "google/protobuf/descriptor.h" @@ -42,18 +41,6 @@ void SingularString::InMsgImpl(Context& ctx, const FieldDescriptor& field, } }) .WithSuffix(""), // This lets `$transform_view$,` work. - {"transform_field_entry", - [&] { - if (field.type() == FieldDescriptor::TYPE_STRING) { - ctx.Emit(R"rs( - $pb$::ProtoStrMut::field_entry_from_bytes( - $pbi$::Private, out - ) - )rs"); - } else { - ctx.Emit("out"); - } - }}, {"view_lifetime", ViewLifetime(accessor_case)}, {"view_self", ViewReceiver(accessor_case)}, {"getter", @@ -80,12 +67,22 @@ void SingularString::InMsgImpl(Context& ctx, const FieldDescriptor& field, [&] { if (accessor_case == AccessorCase::VIEW) return; ctx.Emit(R"rs( - pub fn set_$raw_field_name$(&mut self, val: impl $pb$::SettableValue<$proxied_type$>) { - //~ TODO: Optimize this to not go through the - //~ FieldEntry. - self.$raw_field_name$_mut().set(val); + // TODO: Use IntoProxied once string/bytes types support it. + pub fn set_$raw_field_name$(&mut self, val: impl std::convert::AsRef<$proxied_type$>) { + let string_view: $pbr$::PtrAndLen = + $pbr$::copy_bytes_in_arena_if_needed_by_runtime( + self.as_mutator_message_ref($pbi$::Private), + val.as_ref().into() + ).into(); + + unsafe { + $setter_thunk$( + self.as_mutator_message_ref($pbi$::Private).msg(), + string_view + ); } - )rs"); + } + )rs"); }}, {"hazzer", [&] { @@ -104,74 +101,6 @@ void SingularString::InMsgImpl(Context& ctx, const FieldDescriptor& field, unsafe { $clearer_thunk$(self.raw_msg()) } })rs"); }}, - {"vtable_name", VTableName(field)}, - {"vtable", - [&] { - if (accessor_case != AccessorCase::OWNED) { - return; - } - if (field.has_presence()) { - ctx.Emit({{"default_value", DefaultValue(ctx, field)}}, - R"rs( - // SAFETY: for `string` fields, the default value is verified as valid UTF-8 - const $vtable_name$: &'static $pbi$::BytesOptionalMutVTable = &unsafe { - $pbi$::BytesOptionalMutVTable::new( - $pbi$::Private, - $getter_thunk$, - $setter_thunk$, - $clearer_thunk$, - $default_value$, - ) - }; - )rs"); - } else { - ctx.Emit(R"rs( - const $vtable_name$: &'static $pbi$::BytesMutVTable = - &$pbi$::BytesMutVTable::new( - $pbi$::Private, - $getter_thunk$, - $setter_thunk$, - ); - )rs"); - } - }}, - {"field_mutator_getter", - [&] { - if (accessor_case == AccessorCase::VIEW) { - return; - } - if (field.has_presence()) { - ctx.Emit(R"rs( - fn $raw_field_name$_mut(&mut self) -> $pb$::FieldEntry<'_, $proxied_type$> { - let out = unsafe { - let has = $hazzer_thunk$(self.raw_msg()); - $pbi$::new_vtable_field_entry( - $pbi$::Private, - self.as_mutator_message_ref(), - $Msg$::$vtable_name$, - has, - ) - }; - $transform_field_entry$ - } - )rs"); - } else { - ctx.Emit(R"rs( - fn $raw_field_name$_mut(&mut self) -> $pb$::Mut<'_, $proxied_type$> { - unsafe { - <$pb$::Mut<$proxied_type$>>::from_inner( - $pbi$::Private, - $pbi$::RawVTableMutator::new( - $pbi$::Private, - self.as_mutator_message_ref(), - $Msg$::$vtable_name$, - ) - ) - } - } - )rs"); - } - }}, }, R"rs( $getter$ @@ -179,8 +108,6 @@ void SingularString::InMsgImpl(Context& ctx, const FieldDescriptor& field, $setter$ $hazzer$ $clearer$ - $vtable$ - $field_mutator_getter$ )rs"); } diff --git a/src/google/protobuf/compiler/rust/enum.cc b/src/google/protobuf/compiler/rust/enum.cc index 4184ed09753f..521dcd3ce3bb 100644 --- a/src/google/protobuf/compiler/rust/enum.cc +++ b/src/google/protobuf/compiler/rust/enum.cc @@ -393,7 +393,6 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) { impl $pb$::Proxied for $name$ { type View<'a> = $name$; - type Mut<'a> = $pb$::PrimitiveMut<'a, $name$>; } impl $pb$::ViewProxy<'_> for $name$ { @@ -408,33 +407,6 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) { } } - impl $pb$::SettableValue<$name$> for $name$ { - fn set_on<'msg>( - self, - private: $pbi$::Private, - mut mutator: $pb$::Mut<'msg, $name$> - ) where $name$: 'msg { - mutator.set_primitive(private, self) - } - } - - impl $pb$::ProxiedWithPresence for $name$ { - type PresentMutData<'a> = $pbi$::RawVTableOptionalMutatorData<'a, $name$>; - type AbsentMutData<'a> = $pbi$::RawVTableOptionalMutatorData<'a, $name$>; - - fn clear_present_field( - present_mutator: Self::PresentMutData<'_>, - ) -> Self::AbsentMutData<'_> { - present_mutator.clear($pbi$::Private) - } - - fn set_absent_to_default( - absent_mutator: Self::AbsentMutData<'_>, - ) -> Self::PresentMutData<'_> { - absent_mutator.set_absent_to_default($pbi$::Private) - } - } - unsafe impl $pb$::ProxiedInRepeated for $name$ { fn repeated_len(r: $pb$::View<$pb$::Repeated>) -> usize { $pbr$::cast_enum_repeated_view($pbi$::Private, r).len() @@ -482,8 +454,6 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) { } } - impl $pbi$::PrimitiveWithRawVTable for $name$ {} - // SAFETY: this is an enum type unsafe impl $pbi$::Enum for $name$ { const NAME: &'static str = "$name$"; diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 6ee718fc181c..3cbef149307b 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -246,33 +246,44 @@ void MessageDrop(Context& ctx, const Descriptor& msg) { )rs"); } -void MessageSettableValueForView(Context& ctx, const Descriptor& msg) { +void IntoProxiedForMessage(Context& ctx, const Descriptor& msg) { switch (ctx.opts().kernel) { case Kernel::kCpp: ctx.Emit({{"copy_from_thunk", ThunkName(ctx, msg, "copy_from")}}, R"rs( - impl<'msg> $pb$::SettableValue<$Msg$> for $Msg$View<'msg> { - fn set_on<'dst>( - self, _private: $pbi$::Private, mutator: $pb$::Mut<'dst, $Msg$>) - where $Msg$: 'dst { - unsafe { $copy_from_thunk$(mutator.inner.msg(), self.msg) }; + impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$View<'msg> { + fn into(self, _private: $pbi$::Private) -> $Msg$ { + let dst = $Msg$::new(); + unsafe { $copy_from_thunk$(dst.inner.msg, self.msg) }; + dst } } + + impl $pb$::IntoProxied<$Msg$> for $Msg$ { + fn into(self, _private: $pbi$::Private) -> $Msg$ { + self + } + } )rs"); return; case Kernel::kUpb: - // TODO: Add owned SettableValue impl for upb messages. ctx.Emit({{"minitable", UpbMinitableName(msg)}}, R"rs( - impl<'msg> $pb$::SettableValue<$Msg$> for $Msg$View<'msg> { - fn set_on<'dst>( - self, _private: $pbi$::Private, mutator: $pb$::Mut<'dst, $Msg$>) - where $Msg$: 'dst { + impl<'msg> $pb$::IntoProxied<$Msg$> for $Msg$View<'msg> { + fn into(self, _private: $pbi$::Private) -> $Msg$ { + let dst = $Msg$::new(); unsafe { $pbr$::upb_Message_DeepCopy( - mutator.inner.msg(), + dst.inner.msg, self.msg, $std$::ptr::addr_of!($minitable$), - mutator.inner.arena($pbi$::Private).raw(), + dst.inner.arena.raw(), ) }; + dst + } + } + + impl $pb$::IntoProxied<$Msg$> for $Msg$ { + fn into(self, _private: $pbi$::Private) -> $Msg$ { + self } } )rs"); @@ -817,8 +828,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { AccessorCase::MUT); } }}, - {"settable_impl_for_view", - [&] { MessageSettableValueForView(ctx, msg); }}, + {"into_proxied_impl", [&] { IntoProxiedForMessage(ctx, msg); }}, {"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }}, {"map_value_impl", [&] { MessageProxiedInMapValue(ctx, msg); }}, {"unwrap_upb", @@ -865,6 +875,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>; } @@ -977,17 +990,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { } } - $settable_impl_for_view$ - - impl $pb$::SettableValue<$Msg$> for $Msg$ { - fn set_on<'dst>( - self, _private: $pbi$::Private, mutator: $pb$::Mut<'dst, $Msg$>) - where $Msg$: 'dst { - //~ TODO: b/320701507 - This current will copy the message and then - //~ drop it, this copy would be avoided on upb kernel. - self.as_view().set_on($pbi$::Private, mutator); - } - } + $into_proxied_impl$ $repeated_impl$ $map_value_impl$ @@ -1030,7 +1033,8 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { self.inner.msg() } - fn as_mutator_message_ref(&mut self) -> $pbr$::MutatorMessageRef<'msg> { + pub fn as_mutator_message_ref(&mut self, _private: $pbi$::Private) + -> $pbr$::MutatorMessageRef<'msg> { self.inner } @@ -1076,7 +1080,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { self.inner.msg } - fn as_mutator_message_ref(&mut self) -> $pbr$::MutatorMessageRef { + pub fn as_mutator_message_ref(&mut self, _private: $pbi$::Private) -> $pbr$::MutatorMessageRef { $pbr$::MutatorMessageRef::new($pbi$::Private, &mut self.inner) }