Subject
bit-vec is a no_std-capable Rust crate that provides BitVec, a compact growable vector of bits backed by a Vec of unsigned integer blocks (default u32, generic over the BitBlock trait for u8/u16/u32/u64/usize). The API covers construction, indexed get/set, mutating bitwise operations (and, or, xor, nand, nor, xnor, difference, negate), aggregate predicates (all, any, none, count_ones, count_zeros), iteration (forward, mutable via smart pointers, double-ended), growth (push, pop, grow, truncate, insert, append, split_off), and byte-level conversion (from_bytes, to_bytes). Optional serialization support is wired through serde, borsh, miniserde, and nanoserde derives behind cargo features.
Methodology
The crate consists of a single source file (src/lib.rs, 3186 lines) which was read end-to-end. The published crate contents were diffed against the upstream git tree at the commit recorded in .cargo_vcs_info.json; only the expected Cargo.toml/Cargo.toml.orig/.cargo_vcs_info.json differences are present. Package metadata (Cargo.toml, Cargo.toml.orig, README.md, RELEASES.md) and dev artefacts (.github/workflows/rust.yml, .vscode/settings.json, crusader.sh, .gitignore, .cargo-rdme.toml) were inspected. The 32 implementation-level unit tests in the tests module (lib.rs:1996-3185) were surveyed; CI runs cargo test, cargo miri test (with -Zmiri-strict-provenance), cargo fmt --check, cargo clippy, and cargo doc -Dwarnings. The insert carry-propagation logic was hand-traced at empty, mid-block, end-of-block, and end-of-vector positions; from_bytes/to_bytes round-tripping was verified by tracing the bit-ordering convention. Optional features (serde, borsh, miniserde, nanoserde, std) were treated as in-scope since none are marked unstable.
Results
The crate ships no binaries, no build.rs, no proc-macros, and no install hooks, justifying has-binaries, has-build-exec, and has-install-exec. It performs no network, filesystem, environment, exec, JIT, or interpreter operations and contains no cryptography, justifying uses-network, uses-filesystem, uses-environment, uses-exec, uses-jit, uses-interpreter, uses-crypto, impl-crypto, impl-parser, impl-interpreter, impl-jit, impl-protocol, and impl-algorithm (the crate provides a data structure rather than a standalone algorithm). No threading or synchronization primitives appear; Send/Sync are derived solely through Vec<B> and usize, justifying uses-concurrency and impl-concurrency. The package implements a single data structure (BitVec), justifying impl-datastructure; its operations are linear or constant time without adversarial pathologies, justifying datastructure-impl-bounds. The dependency graph is small and uses well-known crates (serde, borsh, miniserde, nanoserde); dev-dependencies are rand, rand_xorshift, and serde_json. Nothing in the crate exhibits malicious behaviour, justifying is-benign.
Four unsafe fn declarations (storage_mut, get_unchecked, get_unchecked_mut, set_len) make up the entire unsafe surface; there are no unsafe { ... } blocks, no extern "C", and no raw pointer arithmetic. Each carries a # Safety doc block, the bodies are sound under the stated preconditions, and CI exercises them under Miri with strict provenance — justifying uses-unsafe, unsafe-safe, unsafe-documented, unsafe-minimal, and unsafe-tested.
The unit-test suite (32 tests) covers construction, equality, ordering, iteration, push/pop, truncation, growth, append/split_off, all bitwise ops, count_ones/count_zeros across 0..1000-bit sizes, insert at zero/end/block boundaries, and the serde/borsh/miniserde/nanoserde round-trips. These 32 in-module tests justify has-unit-tests; the crate ships no tests/ directory, justifying has-integration-tests. No property-based or fuzz testing is present (justifying has-property-tests and has-fuzz-tests), but the testing is sufficient for a data-structure crate of this complexity, justifying datastructure-impl-tested. datastructure-impl-safe holds: panics occur only on documented capacity overflow or bounds-violation paths, and Miri coverage rules out UB in the unsafe surface.
One medium-severity correctness finding (FINDING-1) was identified: the derived Deserialize impls reconstruct storage and nbits directly and do not validate the two internal invariants the rest of the file relies on (no excess storage blocks, unused bits in the last word zeroed). Hostile serialized input can produce a BitVec whose subsequent operations panic (DoS via set) or silently return incorrect results (all, count_ones, none, eq). Because a safe public API path can produce invariant-violating BitVecs, datastructure-impl-correct is asserted false. Two low-severity quality findings (FINDING-2, FINDING-3) cover an inconsistency in the insert/append length arithmetic and the non-standard clear() semantics that retains the previous length.
Conclusion
bit-vec is a focused, well-bounded data-structure crate with a small unsafe surface that is properly documented and exercised under Miri. The implementation is correct for in-process use. The single non-trivial concern is that the serialization derives do not validate the structural invariants on deserialization; users who deserialize BitVec from untrusted input should layer their own validation (or call truncate(len()) to force fix_last_block) until the derives are replaced with custom impls. The other findings are minor stylistic inconsistencies.