Repository navigation
Fix packing of unaligned integers, narrow integer widths and exclusive byte ranges - #119
Merged
Merged
Conversation
A reference implementation writes each field bit by bit, and the generated pack/unpack code is checked against it for every supported integer width in its natural native type, at bit offsets 0-7 and 13, MSB and LSB, signed and unsigned. Unpacking is also checked with all surrounding bits set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Integer<T, Bits<N>> was only implemented when N needed exactly as many bytes as T, so fields like a u32 in 12 bits, a u16 in 4 bits or [u32; 4] with element_size_bits="12" failed to compile. Every native type now supports all the widths that fit into it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bytes="x..y" ended one byte early, so bytes="0..2" only covered byte 0. The explicit size_bytes on the field was silently overridden by the wrong range, packing a u16 into a single byte. A field whose position and size disagree is now a compile error. Arrays whose bit width can't be evenly split into their elements are also rejected, instead of silently ignoring the leftover bits or panicking in the derive. Fixes #107. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The per-byte source mask was computed from a bit count cast to u8, which wrapped for fields of 32 bytes or more and dropped whole bytes (nested structs, large reserved fields). Adds oracle tests for arrays of unaligned integers and for large unaligned fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
An oracle-based test sweep of how integer fields are placed in the packed bytes. The core bit placement turned out to be correct, but it uncovered four bugs around it:
Integer<T, Bits<N>>was only implemented whenNneeded exactlysize_of::<T>()bytes. That rejected au32field in 12 bits, au16in 4 bits, or[u32; 4]withelement_size_bits="12". Every native type now supports all the widths that fit into it.bytes="x..y"field attribute #107).bytes="0..2"covered only byte 0, and the field's explicitsize_byteswas silently ignored, so au16was packed into a single byte. A field whose position and size disagree is now a compile error.u8, which wrapped. This affected nested structs and large reserved fields.Tests
packing_bit_oracle.rs: a bit-by-bit reference implementation. It checks every supported width at offsets 0–7 and 13, for MSB and LSB, signed and unsigned (540 cases). Unpacking is also checked with all surrounding bits set.packing_narrow_ints.rs: the same checks for widths stored in wider native types (228 cases).packing_arrays_oracle.rs: arrays of unaligned integers (3, 5, 12, 20 and 52 bit elements, and bools) through the new loop-based array codegen, plus large unaligned fields.issue_107.rs: regression test for Derive macro calculates incorrect bit size when using a non-inclusivebytes="x..y"field attribute #107.Behaviour changes
size_bytes/size_bitsdisagree is now a compile error.🤖 Generated with Claude Code