Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove histogram while decoding C-style enums.
  • Loading branch information
finnbear committed Aug 28, 2025
commit 5260315c262b1c6eced6fc53b718f5a31a89eca3
7 changes: 6 additions & 1 deletion bitcode_derive/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ impl crate::shared::Item for Item {
.then(|| {
let private = private(crate_name);
let c_style = inners.is_empty();
quote! { variants: #private::VariantDecoder<#de, #variant_index, #variant_count, #c_style>, }
let histogram = if c_style {
0
} else {
variant_count
};
quote! { variants: #private::VariantDecoder<#de, #variant_index, #variant_count, #histogram>, }
})
.unwrap_or_default();
quote! {
Expand Down
2 changes: 1 addition & 1 deletion src/derive/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<T: Encode> Buffer for OptionEncoder<T> {
}

pub struct OptionDecoder<'a, T: Decode<'a>> {
variants: VariantDecoder<'a, u8, 2, false>,
variants: VariantDecoder<'a, u8, 2, 2>,
some: T::Decoder,
}

Expand Down
2 changes: 1 addition & 1 deletion src/derive/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<T: Encode, E: Encode> Buffer for ResultEncoder<T, E> {
}

pub struct ResultDecoder<'a, T: Decode<'a>, E: Decode<'a>> {
variants: VariantDecoder<'a, u8, 2, false>,
variants: VariantDecoder<'a, u8, 2, 2>,
ok: T::Decoder,
err: E::Decoder,
}
Expand Down
28 changes: 14 additions & 14 deletions src/derive/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ impl<T: Int, const N: usize> Buffer for VariantEncoder<T, N> {
}
}

pub struct VariantDecoder<'a, T: Int, const N: usize, const C_STYLE: bool> {
pub struct VariantDecoder<'a, T: Int, const N: usize, const HISTOGRAM: usize> {
variants: CowSlice<'a, T::Une>,
histogram: [usize; N], // Not required if C_STYLE. TODO don't reserve space for it.
// `HISTOGRAM` is 0 for C style (fieldless) enums.
histogram: [usize; HISTOGRAM],
}

// [(); N] doesn't implement Default.
impl<T: Int, const N: usize, const C_STYLE: bool> Default for VariantDecoder<'_, T, N, C_STYLE> {
impl<T: Int, const N: usize, const HISTOGRAM: usize> Default
for VariantDecoder<'_, T, N, HISTOGRAM>
{
fn default() -> Self {
Self {
variants: Default::default(),
Expand All @@ -48,15 +51,16 @@ impl<T: Int, const N: usize, const C_STYLE: bool> Default for VariantDecoder<'_,
}
}

// C style enums don't require length, so we can skip making a histogram for them.
impl<'a, T: Int, const N: usize> VariantDecoder<'a, T, N, false> {
// C style enums (`HISTOGRAM` = 0) don't require length, so we
// can skip making a histogram for them.
impl<'a, T: Int, const N: usize> VariantDecoder<'a, T, N, N> {
pub fn length(&self, variant_index: u8) -> usize {
self.histogram[variant_index as usize]
}
}

impl<'a, T: Int + Into<usize>, const N: usize, const C_STYLE: bool> View<'a>
for VariantDecoder<'a, T, N, C_STYLE>
impl<'a, T: Int + Into<usize>, const N: usize, const HISTOGRAM: usize> View<'a>
for VariantDecoder<'a, T, N, HISTOGRAM>
{
fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<()> {
assert!(N >= 2);
Expand Down Expand Up @@ -86,18 +90,14 @@ impl<'a, T: Int + Into<usize>, const N: usize, const C_STYLE: bool> View<'a>
check_less_than::<T, N>(unsafe { self.variants.as_slice(length) })?;
} else {
let out = self.variants.cast_mut::<u8>();
if C_STYLE {
unpack_bytes_less_than::<N, 0>(input, length, out)?;
} else {
self.histogram = unpack_bytes_less_than::<N, N>(input, length, out)?;
}
self.histogram = unpack_bytes_less_than::<N, HISTOGRAM>(input, length, out)?;
}
Ok(())
}
}

impl<'a, T: Int + Into<usize>, const N: usize, const C_STYLE: bool> Decoder<'a, T>
for VariantDecoder<'a, T, N, C_STYLE>
impl<'a, T: Int + Into<usize>, const N: usize, const HISTOGRAM: usize> Decoder<'a, T>
for VariantDecoder<'a, T, N, HISTOGRAM>
{
// Guaranteed to output numbers less than N.
#[inline(always)]
Expand Down
Loading