Skip to content

Commit

Permalink
Seperate phantom type generation into a function.
Browse files Browse the repository at this point in the history
  • Loading branch information
kitlith committed Sep 12, 2023
1 parent 62441df commit 50738a5
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions bilge-impl/src/bitsize_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ fn generate_struct(struct_data: &ItemStruct, arb_int: &TokenStream) -> TokenStre
} = struct_data;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

let phantom_ty = generics.type_params().map(|e| &e.ident).map(|ident| quote!(#ident));
let phantom_lt = generics.lifetimes().map(|l| &l.lifetime).map(|lifetime| quote!(& #lifetime ()));
// TODO: integrate user-provided PhantomData somehow? (so that the user can set the variance)
let phantom = phantom_ty.chain(phantom_lt);

let mut fieldless_next_int = 0;
let mut previous_field_sizes = vec![];
let (accessors, (constructor_args, constructor_parts)): (Vec<TokenStream>, (Vec<TokenStream>, Vec<TokenStream>)) = fields
Expand All @@ -91,11 +86,13 @@ fn generate_struct(struct_data: &ItemStruct, arb_int: &TokenStream) -> TokenStre

let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };

let phantom_type = generate_phantom_type(&generics);

quote! {
#vis struct #ident #generics #where_clause {
/// WARNING: modifying this value directly can break invariants
value: #arb_int,
_phantom: ::core::marker::PhantomData<(#(#phantom),*)>
_phantom: ::core::marker::PhantomData<#phantom_type>
}
impl #impl_generics #ident #ty_generics #where_clause {
// #[inline]
Expand All @@ -114,6 +111,18 @@ fn generate_struct(struct_data: &ItemStruct, arb_int: &TokenStream) -> TokenStre
}
}

/// Returns a tuple of types and references to unit using lifetime parameters, or unit if there are no generics.
/// If a single generic is present, it'll be used directly.
fn generate_phantom_type(generics: &Generics) -> TokenStream {
let phantom_ty = generics.type_params().map(|e| &e.ident).map(|ident| quote!(#ident));
let phantom_lt = generics.lifetimes().map(|l| &l.lifetime).map(|lifetime| quote!(& #lifetime ()));
// TODO: integrate user-provided PhantomData somehow? (so that the user can set the variance)
let phantom = phantom_ty.chain(phantom_lt);
quote! {
(#(#phantom),*)
}
}

fn generate_field(field: &Field, field_offset: &TokenStream, fieldless_next_int: &mut usize) -> (TokenStream, (TokenStream, TokenStream)) {
let Field { ident, ty, .. } = field;
let name = if let Some(ident) = ident {
Expand Down

0 comments on commit 50738a5

Please sign in to comment.