diff --git a/protobuf-codegen/src/gen/field/mod.rs b/protobuf-codegen/src/gen/field/mod.rs index 79a16e05e..54e17b843 100644 --- a/protobuf-codegen/src/gen/field/mod.rs +++ b/protobuf-codegen/src/gen/field/mod.rs @@ -185,40 +185,43 @@ impl<'a> FieldGen<'a> { } RuntimeFieldType::Repeated(..) => { let elem = field_elem(&field, root_scope, &customize); - - FieldKind::Repeated(RepeatedField { - elem, - packed: field - .field - .proto() - .options - .get_or_default() - .packed - .unwrap_or(match field.message.scope.file_scope.syntax() { - Syntax::Proto2 => false, - // in proto3, repeated primitive types are packed by default - Syntax::Proto3 => match field.field.proto().type_() { - Type::TYPE_DOUBLE - | Type::TYPE_FLOAT - | Type::TYPE_INT64 - | Type::TYPE_UINT64 - | Type::TYPE_INT32 - | Type::TYPE_FIXED64 - | Type::TYPE_FIXED32 - | Type::TYPE_BOOL - | Type::TYPE_UINT32 - | Type::TYPE_SFIXED32 - | Type::TYPE_SFIXED64 - | Type::TYPE_SINT32 - | Type::TYPE_SINT64 => true, - Type::TYPE_STRING - | Type::TYPE_GROUP - | Type::TYPE_MESSAGE - | Type::TYPE_BYTES - | Type::TYPE_ENUM => false, - }, - }), - }) + let primitive = match field.field.proto().type_() { + Type::TYPE_DOUBLE + | Type::TYPE_FLOAT + | Type::TYPE_INT64 + | Type::TYPE_UINT64 + | Type::TYPE_INT32 + | Type::TYPE_FIXED64 + | Type::TYPE_FIXED32 + | Type::TYPE_BOOL + | Type::TYPE_UINT32 + | Type::TYPE_SFIXED32 + | Type::TYPE_SFIXED64 + | Type::TYPE_SINT32 + | Type::TYPE_SINT64 => true, + Type::TYPE_STRING + | Type::TYPE_GROUP + | Type::TYPE_MESSAGE + | Type::TYPE_BYTES + | Type::TYPE_ENUM => false, + }; + let packed = field + .field + .proto() + .options + .get_or_default() + .packed + .unwrap_or(match field.message.scope.file_scope.syntax() { + Syntax::Proto2 => false, + // in proto3, repeated primitive types are packed by default + Syntax::Proto3 => primitive, + }); + if packed && !primitive { + anyhow::bail!( + "[packed = true] can only be specified for repeated primitive fields" + ); + } + FieldKind::Repeated(RepeatedField { elem, packed }) } RuntimeFieldType::Singular(..) => { let elem = field_elem(&field, root_scope, &customize);