Skip to content

Commit 846c452

Browse files
authored
fix(prost-build): Prevent repeated fields to be boxed (#1237)
Repeated fields are stored in a `Vec`, and therefore they are already heap allocated. BREAKING CHANGE: A repeated field that is manually marked as boxed was typed as `Vec<Box<T>>`. Those fields are now simply typed as `Vec<T>` to prevent double indirection. The `boxed` configuration is effectively ignored for repeated fields.
1 parent bb81b3c commit 846c452

File tree

4 files changed

+13
-13
lines changed

4 files changed

+13
-13
lines changed

prost-build/src/context.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,12 @@ impl<'a> Context<'a> {
141141
oneof: Option<&str>,
142142
field: &FieldDescriptorProto,
143143
) -> bool {
144-
let repeated = field.label() == Label::Repeated;
144+
if field.label() == Label::Repeated {
145+
// Repeated field are stored in Vec, therefore it is already heap allocated
146+
return false;
147+
}
145148
let fd_type = field.r#type();
146-
if !repeated
147-
&& (fd_type == Type::Message || fd_type == Type::Group)
149+
if (fd_type == Type::Message || fd_type == Type::Group)
148150
&& self
149151
.message_graph
150152
.is_nested(field.type_name(), fq_message_name)
@@ -161,13 +163,6 @@ impl<'a> Context<'a> {
161163
.get_first_field(&config_path, field.name())
162164
.is_some()
163165
{
164-
if repeated {
165-
println!(
166-
"cargo:warning=\
167-
Field X is repeated and manually marked as boxed. \
168-
This is deprecated and support will be removed in a later release"
169-
);
170-
}
171166
return true;
172167
}
173168
false

tests/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ fn main() {
172172
prost_build::Config::new()
173173
.boxed("Foo.bar")
174174
.boxed("Foo.oneof_field.box_qux")
175+
.boxed("Foo.boxed_bar_list")
175176
.compile_protos(&[src.join("boxed_field.proto")], includes)
176177
.unwrap();
177178

tests/src/boxed_field.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ message Foo {
88
string baz = 2;
99
Bar box_qux = 3;
1010
}
11+
repeated Bar boxed_bar_list = 4;
1112
}
1213

1314
message Bar {

tests/src/boxed_field.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ include!(concat!(env!("OUT_DIR"), "/boxed_field.rs"));
33
use self::foo::OneofField;
44

55
#[test]
6-
/// Confirm `Foo::bar` and `OneofField::BoxQux` is boxed by creating an instance
6+
/// - Confirm `Foo::bar` and `OneofField::BoxQux` is boxed by creating an instance
7+
/// - `Foo::boxed_bar_list` should not be boxed as it is a `Vec`, therefore it is already heap allocated
78
fn test_boxed_field() {
89
use alloc::boxed::Box;
9-
let _ = Foo {
10+
use alloc::vec::Vec;
11+
let foo = Foo {
1012
bar: Some(Box::new(Bar {})),
1113
oneof_field: Some(OneofField::BoxQux(Box::new(Bar {}))),
14+
boxed_bar_list: Vec::from([Bar {}]),
1215
};
1316
let _ = Foo {
14-
bar: Some(Box::new(Bar {})),
1517
oneof_field: Some(OneofField::Baz("hello".into())),
18+
..foo
1619
};
1720
}

0 commit comments

Comments
 (0)