Move `msg.merge_from(othermsg)` onto a trait fn

PiperOrigin-RevId: 659662640
pull/17718/head
Protobuf Team Bot 7 months ago committed by Copybara-Service
parent 3281605ad4
commit 0f02d8459b
  1. 11
      rust/codegen_traits.rs
  2. 2
      rust/prelude.rs
  3. 2
      rust/proto_macro.rs
  4. 2
      rust/shared.rs
  5. 2
      rust/test/shared/merge_from_test.rs
  6. 53
      src/google/protobuf/compiler/rust/message.cc

@ -14,7 +14,7 @@ use create::Parse;
use interop::{MessageMutInterop, MessageViewInterop, OwnedMessageInterop}; use interop::{MessageMutInterop, MessageViewInterop, OwnedMessageInterop};
use read::Serialize; use read::Serialize;
use std::fmt::Debug; use std::fmt::Debug;
use write::{Clear, ClearAndParse}; use write::{Clear, ClearAndParse, MergeFrom};
/// A trait that all generated owned message types implement. /// A trait that all generated owned message types implement.
pub trait Message: SealedInternal pub trait Message: SealedInternal
@ -24,7 +24,7 @@ pub trait Message: SealedInternal
// Read traits: // Read traits:
+ Debug + Serialize + Debug + Serialize
// Write traits: // Write traits:
+ Clear + ClearAndParse + Clear + ClearAndParse + MergeFrom
// Thread safety: // Thread safety:
+ Send + Sync + Send + Sync
// Copy/Clone: // Copy/Clone:
@ -57,7 +57,7 @@ pub trait MessageMut<'msg>: SealedInternal
+ Debug + Serialize + Debug + Serialize
// Write traits: // Write traits:
// TODO: MsgMut should impl ClearAndParse. // TODO: MsgMut should impl ClearAndParse.
+ Clear + Clear + MergeFrom
// Thread safety: // Thread safety:
+ Sync + Sync
// Copy/Clone: // Copy/Clone:
@ -94,6 +94,7 @@ pub(crate) mod read {
/// traits. /// traits.
pub(crate) mod write { pub(crate) mod write {
use super::SealedInternal; use super::SealedInternal;
use crate::AsView;
pub trait Clear: SealedInternal { pub trait Clear: SealedInternal {
fn clear(&mut self); fn clear(&mut self);
@ -102,6 +103,10 @@ pub(crate) mod write {
pub trait ClearAndParse: SealedInternal { pub trait ClearAndParse: SealedInternal {
fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), crate::ParseError>; fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), crate::ParseError>;
} }
pub trait MergeFrom: AsView + SealedInternal {
fn merge_from(&mut self, src: impl AsView<Proxied = Self::Proxied>);
}
} }
/// Traits related to interop with C or C++. /// Traits related to interop with C or C++.

@ -11,6 +11,6 @@
//! or less common items should be imported normally. //! or less common items should be imported normally.
pub use crate::{ pub use crate::{
proto, AsMut, AsView, Clear, ClearAndParse, IntoMut, IntoView, Message, MessageMut, proto, AsMut, AsView, Clear, ClearAndParse, IntoMut, IntoView, MergeFrom, Message, MessageMut,
MessageView, Parse, Serialize, MessageView, Parse, Serialize,
}; };

@ -50,7 +50,7 @@ macro_rules! proto_internal {
}; };
(@merge $msg:ident ..$expr:expr) => { (@merge $msg:ident ..$expr:expr) => {
$msg.merge_from($expr); $crate::MergeFrom::merge_from(&mut $msg, $expr);
}; };
// @msg rules are used to set the fields of the message. There is a lot of duplication here // @msg rules are used to set the fields of the message. There is a lot of duplication here

@ -26,7 +26,7 @@ pub mod __public {
create::Parse, create::Parse,
interop::{MessageMutInterop, MessageViewInterop, OwnedMessageInterop}, interop::{MessageMutInterop, MessageViewInterop, OwnedMessageInterop},
read::Serialize, read::Serialize,
write::{Clear, ClearAndParse}, write::{Clear, ClearAndParse, MergeFrom},
Message, MessageMut, MessageView, Message, MessageMut, MessageView,
}; };
pub use crate::cord::{ProtoBytesCow, ProtoStringCow}; pub use crate::cord::{ProtoBytesCow, ProtoStringCow};

@ -1,5 +1,5 @@
use googletest::prelude::*; use googletest::prelude::*;
use protobuf::proto; use protobuf::prelude::*;
use unittest_rust_proto::{NestedTestAllTypes, TestAllTypes}; use unittest_rust_proto::{NestedTestAllTypes, TestAllTypes};
#[googletest::test] #[googletest::test]

@ -334,7 +334,7 @@ void UpbGeneratedMessageTraitImpls(Context& ctx, const Descriptor& msg) {
} }
} }
void MessageMergeFrom(Context& ctx, const Descriptor& msg) { void MessageMutMergeFrom(Context& ctx, const Descriptor& msg) {
switch (ctx.opts().kernel) { switch (ctx.opts().kernel) {
case Kernel::kCpp: case Kernel::kCpp:
ctx.Emit( ctx.Emit(
@ -342,10 +342,12 @@ void MessageMergeFrom(Context& ctx, const Descriptor& msg) {
{"merge_from_thunk", ThunkName(ctx, msg, "merge_from")}, {"merge_from_thunk", ThunkName(ctx, msg, "merge_from")},
}, },
R"rs( R"rs(
pub fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) { impl $pb$::MergeFrom for $Msg$Mut<'_> {
// SAFETY: self and src are both valid `$Msg$`s. fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) {
unsafe { // SAFETY: self and src are both valid `$Msg$`s.
$merge_from_thunk$(self.raw_msg(), src.as_view().raw_msg()); unsafe {
$merge_from_thunk$(self.raw_msg(), src.as_view().raw_msg());
}
} }
} }
)rs"); )rs");
@ -353,17 +355,19 @@ void MessageMergeFrom(Context& ctx, const Descriptor& msg) {
case Kernel::kUpb: case Kernel::kUpb:
ctx.Emit( ctx.Emit(
R"rs( R"rs(
pub fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) { impl $pb$::MergeFrom for $Msg$Mut<'_> {
// SAFETY: self and src are both valid `$Msg$`s. fn merge_from(&mut self, src: impl $pb$::AsView<Proxied = $Msg$>) {
unsafe { // SAFETY: self and src are both valid `$Msg$`s.
assert!( unsafe {
$pbr$::upb_Message_MergeFrom(self.raw_msg(), assert!(
src.as_view().raw_msg(), $pbr$::upb_Message_MergeFrom(self.raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE, src.as_view().raw_msg(),
// Use a nullptr for the ExtensionRegistry. <Self as $pbr$::AssociatedMiniTable>::MINI_TABLE,
$std$::ptr::null(), // Use a nullptr for the ExtensionRegistry.
self.arena().raw()) $std$::ptr::null(),
); self.arena().raw())
);
}
} }
} }
)rs"); )rs");
@ -853,6 +857,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
{"Msg::clear_and_parse", [&] { MessageClearAndParse(ctx, msg); }}, {"Msg::clear_and_parse", [&] { MessageClearAndParse(ctx, msg); }},
{"Msg::drop", [&] { MessageDrop(ctx, msg); }}, {"Msg::drop", [&] { MessageDrop(ctx, msg); }},
{"Msg::debug", [&] { MessageDebug(ctx, msg); }}, {"Msg::debug", [&] { MessageDebug(ctx, msg); }},
{"MsgMut::merge_from", [&] { MessageMutMergeFrom(ctx, msg); }},
{"Msg_externs", [&] { MessageExterns(ctx, msg); }}, {"Msg_externs", [&] { MessageExterns(ctx, msg); }},
{"accessor_fns", {"accessor_fns",
[&] { [&] {
@ -955,7 +960,6 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
{"into_proxied_impl", [&] { IntoProxiedForMessage(ctx, msg); }}, {"into_proxied_impl", [&] { IntoProxiedForMessage(ctx, msg); }},
{"upb_generated_message_trait_impls", {"upb_generated_message_trait_impls",
[&] { UpbGeneratedMessageTraitImpls(ctx, msg); }}, [&] { UpbGeneratedMessageTraitImpls(ctx, msg); }},
{"msg_merge_from", [&] { MessageMergeFrom(ctx, msg); }},
{"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }}, {"repeated_impl", [&] { MessageProxiedInRepeated(ctx, msg); }},
{"map_value_impl", [&] { MessageProxiedInMapValue(ctx, msg); }}, {"map_value_impl", [&] { MessageProxiedInMapValue(ctx, msg); }},
{"unwrap_upb", {"unwrap_upb",
@ -998,6 +1002,13 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
} }
} }
impl $pb$::MergeFrom for $Msg$ {
fn merge_from<'src>(&mut self, src: impl $pb$::AsView<Proxied = Self>) {
let mut m = self.as_mut();
$pb$::MergeFrom::merge_from(&mut m, src)
}
}
impl $pb$::Serialize for $Msg$ { impl $pb$::Serialize for $Msg$ {
fn serialize(&self) -> Result<Vec<u8>, $pb$::SerializeError> { fn serialize(&self) -> Result<Vec<u8>, $pb$::SerializeError> {
$pb$::AsView::as_view(self).serialize() $pb$::AsView::as_view(self).serialize()
@ -1141,6 +1152,8 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
} }
} }
$MsgMut::merge_from$
#[allow(dead_code)] #[allow(dead_code)]
impl<'msg> $Msg$Mut<'msg> { impl<'msg> $Msg$Mut<'msg> {
#[doc(hidden)] #[doc(hidden)]
@ -1173,8 +1186,6 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
$pb$::AsView::as_view(self).to_owned() $pb$::AsView::as_view(self).to_owned()
} }
$msg_merge_from$
$raw_arena_getter_for_msgmut$ $raw_arena_getter_for_msgmut$
$accessor_fns_for_muts$ $accessor_fns_for_muts$
@ -1248,10 +1259,6 @@ void GenerateRs(Context& ctx, const Descriptor& msg) {
$Msg$Mut::new($pbi$::Private, &mut self.inner) $Msg$Mut::new($pbi$::Private, &mut self.inner)
} }
pub fn merge_from<'src>(&mut self, src: impl $pb$::Proxy<'src, Proxied = $Msg$>) {
self.as_mut().merge_from(src);
}
$accessor_fns$ $accessor_fns$
} // impl $Msg$ } // impl $Msg$

Loading…
Cancel
Save