Skip to content

Commit

Permalink
[wip] Practice good Self hygiene
Browse files Browse the repository at this point in the history
Fixes #2116
  • Loading branch information
jswrenn committed Dec 3, 2024
1 parent 7431cbd commit 1a1dc4a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/util/macro_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ use crate::{
Immutable, IntoBytes, Ptr, TryFromBytes, Unalign, ValidityError,
};

/// TODO
pub trait Field<const IDX: usize> {
type Type: ?Sized;
}

#[cfg_attr(
zerocopy_diagnostic_on_unimplemented_1_78_0,
diagnostic::on_unimplemented(
Expand Down
36 changes: 32 additions & 4 deletions zerocopy-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,32 @@ fn derive_known_layout_inner(ast: &DeriveInput, _top_level: Trait) -> Result<Tok
Default::default()
};

let trailing_field_index = leading_fields.len();
let leading_field_indices = 0..trailing_field_index;

let trailing_field_ty = quote! {
<#ident #ty_generics as
::zerocopy::util::macro_util::Field<{#trailing_field_index}>
>::Type
};

let methods = make_methods(&parse_quote! {
<#trailing_field_ty as ::zerocopy::KnownLayout>::MaybeUninit
});

let field_impls = fields.iter().enumerate().map(|(idx, (_, ty))| quote!{
impl #impl_generics ::zerocopy::util::macro_util::Field<{#idx}> for #ident #ty_generics
where
#trailing_field_ty: ::zerocopy::KnownLayout,
#predicates
{
type Type = #ty;
}
});

quote! {
#(#field_impls)*

// SAFETY: This has the same layout as the derive target type,
// except that it admits uninit bytes. This is ensured by using the
// same repr as the target type, and by using field types which have
Expand All @@ -279,11 +300,17 @@ fn derive_known_layout_inner(ast: &DeriveInput, _top_level: Trait) -> Result<Tok
#repr
#[doc(hidden)]
#vis struct __ZerocopyKnownLayoutMaybeUninit<#params> (
#(::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit<#leading_fields_tys>,)*
#(::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit<
<#ident #ty_generics as
::zerocopy::util::macro_util::Field<{#leading_field_indices}>
>::Type
>,)*
<#trailing_field_ty as ::zerocopy::KnownLayout>::MaybeUninit
)
where
#trailing_field_ty: ::zerocopy::KnownLayout,
#trailing_field_ty: ::zerocopy::KnownLayout<
PointerMetadata = <#ident #ty_generics as KnownLayout>::PointerMetadata
>,
#predicates;

// SAFETY: We largely defer to the `KnownLayout` implementation on
Expand All @@ -294,10 +321,11 @@ fn derive_known_layout_inner(ast: &DeriveInput, _top_level: Trait) -> Result<Tok
// `__ZerocopyKnownLayoutMaybeUninit` admits uninit bytes.
unsafe impl #impl_generics ::zerocopy::KnownLayout for __ZerocopyKnownLayoutMaybeUninit #ty_generics
where
#trailing_field_ty: ::zerocopy::KnownLayout,
// This bound may appear to be superfluous, but is required
// on our MSRV (1.55) to avoid an ICE.
<#trailing_field_ty as ::zerocopy::KnownLayout>::MaybeUninit: ::zerocopy::KnownLayout,
#trailing_field_ty: ::zerocopy::KnownLayout<
PointerMetadata = <#ident #ty_generics as KnownLayout>::PointerMetadata
>,
#predicates
{
#[allow(clippy::missing_inline_in_public_items)]
Expand Down

0 comments on commit 1a1dc4a

Please sign in to comment.