diff --git a/serde_derive/src/internals/attr.rs b/serde_derive/src/internals/attr.rs index 44f757021..691a156d2 100644 --- a/serde_derive/src/internals/attr.rs +++ b/serde_derive/src/internals/attr.rs @@ -597,8 +597,19 @@ impl Container { for attr in &item.attrs { if attr.path.is_ident("repr") { let _ = attr.parse_args_with(|input: ParseStream| { - is_packed |= input.parse::()? == "packed"; - Ok(()) + input.step(|cursor| { + let mut rest = *cursor; + while let Some((tt, next)) = rest.token_tree() { + match &tt { + TokenTree::Ident(ident) if ident == "packed" => { + is_packed |= true; + return Ok(((), next)); + } + _ => rest = next, + } + } + Err(cursor.error("no `packed` was found in the reprs")) + }) }); } } diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index c0c807ec7..c6c0c1785 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -1878,3 +1878,31 @@ fn test_internally_tagged_newtype_variant_containing_unit_struct() { ], ); } + +#[deny(safe_packed_borrows)] +#[test] +fn test_packed_struct_can_derive_serialize() { + #[derive(Copy, Clone, Serialize)] + #[repr(packed, C)] + struct PackedC { + t: f32, + } + + #[derive(Copy, Clone, Serialize)] + #[repr(C, packed)] + struct CPacked { + t: f32, + } + + #[derive(Copy, Clone, Serialize)] + #[repr(C, packed(2))] + struct CPacked2 { + t: f32, + } + + #[derive(Copy, Clone, Serialize)] + #[repr(packed(2), C)] + struct Packed2C { + t: f32, + } +}