Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove PrimitiveMut and related vtable types #16626

Merged
merged 1 commit into from Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion rust/BUILD
Expand Up @@ -48,8 +48,8 @@ rust_library(
PROTOBUF_SHARED = [
"enum.rs",
"internal.rs",
"optional.rs",
"primitive.rs",
"optional.rs",
"proxied.rs",
"repeated.rs",
"shared.rs",
Expand Down
1 change: 0 additions & 1 deletion rust/cpp.rs
Expand Up @@ -238,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)]
Expand Down
5 changes: 2 additions & 3 deletions rust/internal.rs
Expand Up @@ -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;

Expand Down
129 changes: 1 addition & 128 deletions rust/primitive.rs
Expand Up @@ -4,96 +4,7 @@
// 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, MutProxied, 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<T>) {
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),*) => {
Expand All @@ -102,10 +13,6 @@ macro_rules! impl_singular_primitives {
type View<'msg> = $t;
}

impl MutProxied for $t {
type Mut<'msg> = PrimitiveMut<'msg, $t>;
}

impl<'msg> ViewProxy<'msg> for $t {
type Proxied = $t;

Expand All @@ -118,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
)*
}
Expand Down
1 change: 0 additions & 1 deletion rust/shared.rs
Expand Up @@ -25,7 +25,6 @@ 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::{
IntoProxied, Mut, MutProxied, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View,
Expand Down
1 change: 0 additions & 1 deletion rust/upb.rs
Expand Up @@ -66,7 +66,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 {
Expand Down
135 changes: 2 additions & 133 deletions rust/vtable.rs
Expand Up @@ -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, MutProxied, MutProxy, Optional, PresentField, PrimitiveMut,
AbsentField, FieldEntry, Mut, MutProxied, MutProxy, Optional, PresentField,
ProxiedWithPresence, View, ViewProxy,
};
use std::fmt::{self, Debug};
Expand Down Expand Up @@ -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<T> {
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<T> {
pub(crate) base: PrimitiveVTable<T>,
pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage),
pub(crate) default: T,
}

impl<T> PrimitiveVTable<T> {
#[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<T> PrimitiveOptionalMutVTable<T> {
#[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)]
Expand Down Expand Up @@ -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> MutProxied<View<'msg> = Self, Mut<'msg> = PrimitiveMut<'msg, Self>>
{
}

impl<T: PrimitiveWithRawVTable> ProxiedWithRawVTable for T {
type VTable = PrimitiveVTable<T>;

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<T: PrimitiveWithRawVTable> ProxiedWithRawOptionalVTable for T {
type OptionalVTable = PrimitiveOptionalMutVTable<T>;

fn upcast_vtable(
_private: Private,
optional_vtable: &'static Self::OptionalVTable,
) -> &'static Self::VTable {
&optional_vtable.base
}
}

impl<T: PrimitiveWithRawVTable> 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
}
}