Skip to content

Commit

Permalink
fix: boxed oneof field
Browse files Browse the repository at this point in the history
fix tokio-rs#1159

Signed-off-by: xxchan <[email protected]>
  • Loading branch information
xxchan committed Dec 20, 2024
1 parent 56b9602 commit acb7e5d
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 11 deletions.
20 changes: 10 additions & 10 deletions prost-build/src/code_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,21 +639,21 @@ impl CodeGenerator<'_> {

self.push_indent();
let ty_tag = self.field_type_tag(&field.descriptor);
self.buf.push_str(&format!(
"#[prost({}, tag=\"{}\")]\n",
ty_tag,
field.descriptor.number()
));
self.append_field_attributes(&oneof_name, field.descriptor.name());

self.push_indent();
let ty = self.resolve_type(&field.descriptor, fq_message_name);

let boxed = self.boxed(
&field.descriptor,
fq_message_name,
Some(oneof.descriptor.name()),
);
self.buf.push_str(&format!("#[prost({}", ty_tag));
if boxed {
self.buf.push_str(", boxed");
}
self.buf
.push_str(&format!(", tag=\"{}\")]\n", field.descriptor.number()));
self.append_field_attributes(&oneof_name, field.descriptor.name());

self.push_indent();
let ty = self.resolve_type(&field.descriptor, fq_message_name);

debug!(
" oneof: {:?}, type: {:?}, boxed: {}",
Expand Down
6 changes: 5 additions & 1 deletion prost-derive/src/field/oneof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_str, Expr, ExprLit, Ident, Lit, Meta, MetaNameValue, Path};

use crate::field::{set_option, tags_attr};
use crate::field::{set_bool, set_option, tags_attr, word_attr};

#[derive(Clone)]
pub struct Field {
Expand All @@ -15,6 +15,8 @@ impl Field {
pub fn new(attrs: &[Meta]) -> Result<Option<Field>, Error> {
let mut ty = None;
let mut tags = None;
let mut boxed = false;

let mut unknown_attrs = Vec::new();

for attr in attrs {
Expand All @@ -34,6 +36,8 @@ impl Field {
set_option(&mut ty, t, "duplicate oneof attribute")?;
} else if let Some(t) = tags_attr(attr)? {
set_option(&mut tags, t, "duplicate tags attributes")?;
} else if word_attr("boxed", attr) {
set_bool(&mut boxed, "duplicate boxed attribute")?;
} else {
unknown_attrs.push(attr);
}
Expand Down
1 change: 1 addition & 0 deletions tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ fn main() {

prost_build::Config::new()
.boxed("Foo.bar")
.boxed("Foo.oneof_field.box_qux")
.compile_protos(&[src.join("boxed_field.proto")], includes)
.unwrap();

Expand Down
4 changes: 4 additions & 0 deletions tests/src/boxed_field.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ package boxed_field;

message Foo {
Bar bar = 1;
oneof oneof_field {
string baz = 2;
Bar box_qux = 3;
}
}

message Bar {
Expand Down
2 changes: 2 additions & 0 deletions tests/src/boxed_field.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
include!(concat!(env!("OUT_DIR"), "/boxed_field.rs"));
use foo::OneofField;

#[test]
/// Confirm `Foo::bar` is boxed by creating an instance
fn test_bar_is_boxed() {
use alloc::boxed::Box;
let _ = Foo {
bar: Some(Box::new(Bar {})),
oneof_field: Some(OneofField::BoxQux(Box::new(Bar {}))),
};
}

0 comments on commit acb7e5d

Please sign in to comment.