Skip to content

Commit ddd6a33

Browse files
committed
fix(prost-build): Remove derived(Copy) on boxed fields
1 parent 644c328 commit ddd6a33

File tree

4 files changed

+67
-54
lines changed

4 files changed

+67
-54
lines changed

prost-build/src/code_generator.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl<'a> CodeGenerator<'a> {
230230
self.push_indent();
231231
self.buf.push_str(&format!(
232232
"#[derive(Clone, {}PartialEq, {}::Message)]\n",
233-
if self.message_graph.can_message_derive_copy(&fq_message_name) {
233+
if self.can_message_derive_copy(&fq_message_name) {
234234
"Copy, "
235235
} else {
236236
""
@@ -615,10 +615,10 @@ impl<'a> CodeGenerator<'a> {
615615
self.append_enum_attributes(&oneof_name);
616616
self.push_indent();
617617

618-
let can_oneof_derive_copy = oneof.fields.iter().all(|field| {
619-
self.message_graph
620-
.can_field_derive_copy(fq_message_name, &field.descriptor)
621-
});
618+
let can_oneof_derive_copy = oneof
619+
.fields
620+
.iter()
621+
.all(|field| self.can_field_derive_copy(fq_message_name, &field.descriptor));
622622
self.buf.push_str(&format!(
623623
"#[derive(Clone, {}PartialEq, {}::Oneof)]\n",
624624
if can_oneof_derive_copy { "Copy, " } else { "" },
@@ -1120,6 +1120,60 @@ impl<'a> CodeGenerator<'a> {
11201120
message_name,
11211121
)
11221122
}
1123+
1124+
/// Returns `true` if this message can automatically derive Copy trait.
1125+
fn can_message_derive_copy(&self, fq_message_name: &str) -> bool {
1126+
assert_eq!(".", &fq_message_name[..1]);
1127+
self.message_graph
1128+
.get_message(fq_message_name)
1129+
.unwrap()
1130+
.field
1131+
.iter()
1132+
.all(|field| self.can_field_derive_copy(fq_message_name, field))
1133+
}
1134+
1135+
/// Returns `true` if the type of this field allows deriving the Copy trait.
1136+
fn can_field_derive_copy(&self, fq_message_name: &str, field: &FieldDescriptorProto) -> bool {
1137+
assert_eq!(".", &fq_message_name[..1]);
1138+
1139+
// repeated field cannot derive Copy
1140+
if field.label() == Label::Repeated {
1141+
false
1142+
} else if field.r#type() == Type::Message {
1143+
// nested and boxed messages cannot derive Copy
1144+
if self
1145+
.message_graph
1146+
.is_nested(field.type_name(), fq_message_name)
1147+
|| self
1148+
.config
1149+
.boxed
1150+
.get_first_field(fq_message_name, field.name())
1151+
.is_some()
1152+
{
1153+
false
1154+
} else {
1155+
self.can_message_derive_copy(field.type_name())
1156+
}
1157+
} else {
1158+
matches!(
1159+
field.r#type(),
1160+
Type::Float
1161+
| Type::Double
1162+
| Type::Int32
1163+
| Type::Int64
1164+
| Type::Uint32
1165+
| Type::Uint64
1166+
| Type::Sint32
1167+
| Type::Sint64
1168+
| Type::Fixed32
1169+
| Type::Fixed64
1170+
| Type::Sfixed32
1171+
| Type::Sfixed64
1172+
| Type::Bool
1173+
| Type::Enum
1174+
)
1175+
}
1176+
}
11231177
}
11241178

11251179
/// Returns `true` if the repeated field type can be packed.

prost-build/src/fixtures/field_attributes/_expected_field_attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Foo {
1919
#[prost(string, tag="1")]
2020
pub foo: ::prost::alloc::string::String,
2121
}
22-
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
22+
#[derive(Clone, PartialEq, ::prost::Message)]
2323
pub struct Bar {
2424
#[prost(message, optional, boxed, tag="1")]
2525
pub qux: ::core::option::Option<::prost::alloc::boxed::Box<Qux>>,

prost-build/src/fixtures/field_attributes/_expected_field_attributes_formatted.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct Foo {
1919
#[prost(string, tag = "1")]
2020
pub foo: ::prost::alloc::string::String,
2121
}
22-
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
22+
#[derive(Clone, PartialEq, ::prost::Message)]
2323
pub struct Bar {
2424
#[prost(message, optional, boxed, tag = "1")]
2525
pub qux: ::core::option::Option<::prost::alloc::boxed::Box<Qux>>,

prost-build/src/message_graph.rs

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use petgraph::Graph;
66

77
use prost_types::{
88
field_descriptor_proto::{Label, Type},
9-
DescriptorProto, FieldDescriptorProto, FileDescriptorProto,
9+
DescriptorProto, FileDescriptorProto,
1010
};
1111

1212
/// `MessageGraph` builds a graph of messages whose edges correspond to nesting.
@@ -74,6 +74,11 @@ impl MessageGraph {
7474
}
7575
}
7676

77+
/// Try get a message descriptor from current message graph
78+
pub fn get_message(&self, message: &str) -> Option<&DescriptorProto> {
79+
self.messages.get(message)
80+
}
81+
7782
/// Returns true if message type `inner` is nested in message type `outer`.
7883
pub fn is_nested(&self, outer: &str, inner: &str) -> bool {
7984
let outer = match self.index.get(outer) {
@@ -87,50 +92,4 @@ impl MessageGraph {
8792

8893
has_path_connecting(&self.graph, outer, inner, None)
8994
}
90-
91-
/// Returns `true` if this message can automatically derive Copy trait.
92-
pub fn can_message_derive_copy(&self, fq_message_name: &str) -> bool {
93-
assert_eq!(".", &fq_message_name[..1]);
94-
let msg = self.messages.get(fq_message_name).unwrap();
95-
msg.field
96-
.iter()
97-
.all(|field| self.can_field_derive_copy(fq_message_name, field))
98-
}
99-
100-
/// Returns `true` if the type of this field allows deriving the Copy trait.
101-
pub fn can_field_derive_copy(
102-
&self,
103-
fq_message_name: &str,
104-
field: &FieldDescriptorProto,
105-
) -> bool {
106-
assert_eq!(".", &fq_message_name[..1]);
107-
108-
if field.label() == Label::Repeated {
109-
false
110-
} else if field.r#type() == Type::Message {
111-
if self.is_nested(field.type_name(), fq_message_name) {
112-
false
113-
} else {
114-
self.can_message_derive_copy(field.type_name())
115-
}
116-
} else {
117-
matches!(
118-
field.r#type(),
119-
Type::Float
120-
| Type::Double
121-
| Type::Int32
122-
| Type::Int64
123-
| Type::Uint32
124-
| Type::Uint64
125-
| Type::Sint32
126-
| Type::Sint64
127-
| Type::Fixed32
128-
| Type::Fixed64
129-
| Type::Sfixed32
130-
| Type::Sfixed64
131-
| Type::Bool
132-
| Type::Enum
133-
)
134-
}
135-
}
13695
}

0 commit comments

Comments
 (0)