@@ -2284,15 +2284,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) {
22842284 CopyFrom(from);
22852285 return *this;
22862286 }
2287- inline $classname$& operator=($classname$&& from) noexcept {
2288- if (this == &from) return *this;
2289- if ($pbi$::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
2290- InternalSwap(&from);
2291- } else {
2292- CopyFrom(from);
2293- }
2294- return *this;
2295- }
2287+ $classname$& operator=($classname$&& from) noexcept;
22962288 $decl_verify_func$;
22972289
22982290 inline const $unknown_fields_type$& unknown_fields() const
@@ -2352,12 +2344,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) {
23522344
23532345 explicit $classname$($pb$::Arena* $nullable$ arena);
23542346 $classname$($pb$::Arena* $nullable$ arena, const $classname$& from);
2355- $classname$(
2356- //~
2357- $pb$::Arena* $nullable$ arena, $classname$&& from) noexcept
2358- : $classname$(arena) {
2359- *this = ::std::move(from);
2360- }
2347+ $classname$($pb$::Arena* $nullable$ arena, $classname$&& from) noexcept;
23612348 $arena_dtor$;
23622349 const $pbi$::ClassData* $nonnull$ GetClassData() const PROTOBUF_FINAL;
23632350 static void* $nonnull$ PlacementNew_(
@@ -2416,6 +2403,74 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* p) {
24162403 auto v = p->WithVars (ClassVars (descriptor_, options_));
24172404 auto t = p->WithVars (MakeTrackerCalls (descriptor_, options_));
24182405 if (IsMapEntryMessage (descriptor_)) return ;
2406+
2407+ if (CanUseTrivialCopy ()) {
2408+ p->Emit (R"cc(
2409+ inline $classname$::$classname$($pb$::Arena* $nullable$ arena,
2410+ const $classname$& from)
2411+ #if defined(PROTOBUF_CUSTOM_VTABLE)
2412+ : $superclass$(arena, $classname$_class_data_.base()),
2413+ #else // PROTOBUF_CUSTOM_VTABLE
2414+ : $superclass$(arena),
2415+ #endif // PROTOBUF_CUSTOM_VTABLE
2416+ _impl_(from._impl_) {
2417+ if (ABSL_PREDICT_FALSE(from._internal_metadata_.have_unknown_fields())) {
2418+ $superclass$::CopyFromUFS<$unknown_fields_type$>(from);
2419+ }
2420+ }
2421+
2422+ inline $classname$::$classname$($pb$::Arena* $nullable$ arena,
2423+ $classname$&& from) noexcept
2424+ #if defined(PROTOBUF_CUSTOM_VTABLE)
2425+ : $superclass$(arena, $classname$_class_data_.base()),
2426+ #else // PROTOBUF_CUSTOM_VTABLE
2427+ : $superclass$(arena),
2428+ #endif // PROTOBUF_CUSTOM_VTABLE
2429+ _impl_(from._impl_) {
2430+ if (ABSL_PREDICT_FALSE(from._internal_metadata_.have_unknown_fields())) {
2431+ $superclass$::MoveFromUFS<$unknown_fields_type$>(arena, from);
2432+ }
2433+ }
2434+
2435+ inline $classname$& $classname$::operator=($classname$&& from) noexcept {
2436+ _impl_ = from._impl_;
2437+ if (ABSL_PREDICT_FALSE(from._internal_metadata_.have_unknown_fields())) {
2438+ $superclass$::MoveAssignFromUFS<$unknown_fields_type$>(from);
2439+ }
2440+ return *this;
2441+ }
2442+ )cc" );
2443+
2444+ if (HasGeneratedMethods (descriptor_->file (), options_)) {
2445+ p->Emit (R"cc(
2446+ inline void $classname$::CopyFrom(const $classname$& from) {
2447+ // @@protoc_insertion_point(class_specific_copy_from_start:$full_name$)
2448+ _impl_ = from._impl_;
2449+ if (ABSL_PREDICT_FALSE(from._internal_metadata_.have_unknown_fields())) {
2450+ $superclass$::CopyFromUFS<$unknown_fields_type$>(from);
2451+ }
2452+ }
2453+ )cc" );
2454+ }
2455+ } else {
2456+ p->Emit (R"cc(
2457+ inline $classname$::$classname$($pb$::Arena* $nullable$ arena,
2458+ $classname$&& from) noexcept
2459+ : $classname$(arena) {
2460+ *this = ::std::move(from);
2461+ }
2462+ inline $classname$& $classname$::operator=($classname$&& from) noexcept {
2463+ if (this == &from) return *this;
2464+ if ($pbi$::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
2465+ InternalSwap(&from);
2466+ } else {
2467+ CopyFrom(from);
2468+ }
2469+ return *this;
2470+ }
2471+ )cc" );
2472+ }
2473+
24192474 GenerateFieldAccessorDefinitions (p);
24202475
24212476 // Generate oneof_case() functions.
@@ -3571,7 +3626,9 @@ void MessageGenerator::GenerateStructors(io::Printer* p) {
35713626 )cc" );
35723627
35733628 // Generate the copy constructor.
3574- if (UsingImplicitWeakFields (descriptor_->file (), options_)) {
3629+ if (CanUseTrivialCopy ()) {
3630+ // Do nothing. Already generated as inline.
3631+ } else if (UsingImplicitWeakFields (descriptor_->file (), options_)) {
35753632 // If we are in lite mode and using implicit weak fields, we generate a
35763633 // one-liner copy constructor that delegates to MergeFrom. This saves some
35773634 // code size and also cuts down on the complexity of implicit weak fields.
@@ -3584,21 +3641,6 @@ void MessageGenerator::GenerateStructors(io::Printer* p) {
35843641 MergeFrom(from);
35853642 }
35863643 )cc" );
3587- } else if (CanUseTrivialCopy ()) {
3588- p->Emit (R"cc(
3589- $classname$::$classname$(
3590- //~ Force alignment
3591- $pb$::Arena* $nullable$ arena, const $classname$& from)
3592- #if defined(PROTOBUF_CUSTOM_VTABLE)
3593- : $superclass$(arena, $classname$_class_data_.base()),
3594- #else // PROTOBUF_CUSTOM_VTABLE
3595- : $superclass$(arena),
3596- #endif // PROTOBUF_CUSTOM_VTABLE
3597- _impl_(from._impl_) {
3598- _internal_metadata_.MergeFrom<$unknown_fields_type$>(
3599- from._internal_metadata_);
3600- }
3601- )cc" );
36023644 } else {
36033645 GenerateArenaEnabledCopyConstructor (p);
36043646 }
@@ -4672,6 +4714,7 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) {
46724714
46734715void MessageGenerator::GenerateCopyFrom (io::Printer* p) {
46744716 if (HasSimpleBaseClass (descriptor_, options_)) return ;
4717+ if (CanUseTrivialCopy ()) return ;
46754718 if (HasDescriptorMethods (descriptor_->file (), options_)) {
46764719 // We don't override the generalized CopyFrom (aka that which
46774720 // takes in the Message base class as a parameter); instead we just
0 commit comments