From 0451e53f44c69a04ab4fec86030509e456805521 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Thu, 6 Feb 2025 10:11:04 -0800 Subject: [PATCH] [derive] Fix bug with KnownLayout on repr(packed) (#2307) Fixes #2302 gherrit-pr-id: If68c1724be15c4df3ec936a12cf854908650a639 --- zerocopy-derive/src/lib.rs | 10 +++++++++- zerocopy-derive/src/output_tests.rs | 14 ++++++++------ zerocopy-derive/tests/struct_known_layout.rs | 11 +++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/zerocopy-derive/src/lib.rs b/zerocopy-derive/src/lib.rs index 80698e1e02..2fc4563a0e 100644 --- a/zerocopy-derive/src/lib.rs +++ b/zerocopy-derive/src/lib.rs @@ -332,7 +332,15 @@ fn derive_known_layout_inner(ast: &DeriveInput, _top_level: Trait) -> Result >::Type >,)* - <#trailing_field_ty as ::zerocopy::KnownLayout>::MaybeUninit + // NOTE(#2302): We wrap in `ManuallyDrop` here in case the + // type we're operating on is both generic and + // `repr(packed)`. In that case, Rust needs to know that the + // type is *either* `Sized` or has a trivial `Drop`. + // `ManuallyDrop` has a trivial `Drop`, and so satisfies + // this requirement. + ::zerocopy::util::macro_util::core_reexport::mem::ManuallyDrop< + <#trailing_field_ty as ::zerocopy::KnownLayout>::MaybeUninit + > ) where #trailing_field_ty: ::zerocopy::KnownLayout, diff --git a/zerocopy-derive/src/output_tests.rs b/zerocopy-derive/src/output_tests.rs index f817f998e6..b85adeafef 100644 --- a/zerocopy-derive/src/output_tests.rs +++ b/zerocopy-derive/src/output_tests.rs @@ -198,12 +198,14 @@ fn test_known_layout() { ::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit< as ::zerocopy::util::macro_util::Field<__Zerocopy_Field_0>>::Type, >, - < as ::zerocopy::util::macro_util::Field< - __Zerocopy_Field_1, - >>::Type as ::zerocopy::KnownLayout>::MaybeUninit, + ::zerocopy::util::macro_util::core_reexport::mem::ManuallyDrop< + < as ::zerocopy::util::macro_util::Field< + __Zerocopy_Field_1, + >>::Type as ::zerocopy::KnownLayout>::MaybeUninit + >, ) where { + payload: P, +} + +util_assert_impl_all!(Packet: imp::KnownLayout);