Subject
beef is a smaller, faster drop-in replacement for std::borrow::Cow.
It exposes two variants: beef::Cow (wide), which is three words wide
(pointer + length + an Option<NonZeroUsize> capacity, with None
encoding the borrowed state); and beef::lean::Cow, which on 64-bit
targets is only two words wide (pointer + a packed fat word holding
both length and capacity in 32-bit halves). The smaller layout makes
Cow cheaper to pass by value and to store inside enums or struct
fields. The crate is no_std-compatible and the impl_serde
feature adds Serde support.
Methodology
The published crate was diffed against the upstream Git checkout at the
commit recorded in .cargo_vcs_info.json. All seven source files
(src/lib.rs, src/generic.rs, src/wide.rs, src/lean.rs,
src/traits.rs, src/serde.rs, src/lean.rs; ~1450 lines total) were
read end-to-end. Every unsafe block, every unsafe trait/impl,
and the Capacity impls for Wide and Lean were inspected against
the invariants of Vec::from_raw_parts, String::from_utf8_unchecked,
slice_from_raw_parts, and NonNull::new_unchecked. The
test-generating test! macro in src/lib.rs and the
MIRIFLAGS='-Zmiri-strict-provenance'-driven CI script
(contents/ci/miri.sh) were noted.
Results
All source files are byte-identical between the published crate and
upstream. Cargo.toml differences are limited to cargo's standard
normalisation. The crate ships no binary artefacts (justifying
has-binaries), no build.rs, and no proc-macros (justifying
has-build-exec, has-install-exec). Optional dependencies (serde)
are opt-in via documented features.
src/traits.rs defines an unsafe trait Beef: ToOwned whose contract
is documented at the trait level: T::Owned must have a capacity
word distinct from T, a capacity of 0 must not allocate, and the
owned form must be reconstructable from a *mut T plus capacity.
Implementations for str (backed by String) and [T: Clone]
(backed by Vec<T>) go through Vec::from_raw_parts /
String::from_utf8_unchecked and slice_from_raw_parts, each with
"note on soundness" comments explaining the *const T as *mut T cast
that occurs only on the borrow path (where the resulting pointer is
never dereferenced as *mut). Backs uses-unsafe, unsafe-safe,
unsafe-documented, unsafe-minimal, impl-datastructure, and
datastructure-impl-safe.
src/generic.rs defines Cow<'a, T, U: Capacity>. The state of the
Cow is encoded by querying U::maybe(fat, cap): a borrowed Cow returns
None, and an owned Cow returns Some(capacity). Drop only
reconstructs the owned type when capacity is present, so dropping a
borrowed Cow is a no-op as expected. The Send/Sync impls have the
same bounds as std::borrow::Cow and carry the inline "Safety: Same
bounds as std::borrow::Cow" comment.
src/wide.rs and src/lean.rs are the two Capacity impls. Wide
stores capacity as Option<NonZeroUsize> and is straightforward;
Lean packs (length, capacity) into a single usize by storing
length in the low 32 bits and capacity in the high 32 bits. The owned
path (Capacity::store) explicitly panics if capacity exceeds
u32::MAX. The borrowed path (Capacity::empty and Lean::mask_len)
silently truncates length with & MASK_LO — recorded as
FINDING-1, a low-severity correctness issue: in practice, byte slices
above 4 GiB are rare and on 32-bit targets the issue cannot trigger,
but the silent-vs-panic asymmetry with the owned path is surprising
and the module docs do not explicitly warn about it. datastructure-impl-correct
is therefore false.
The codebase was reviewed for cryptographic, network, filesystem,
environment, exec, JIT, interpreter, and concurrency usage, and none
was found, justifying uses-network, uses-filesystem,
uses-environment, uses-exec, uses-crypto, uses-jit,
uses-interpreter, uses-concurrency, impl-crypto, impl-parser,
impl-interpreter, impl-jit, impl-protocol, impl-algorithm,
impl-concurrency.
Testing is supplied by a test! macro in src/lib.rs that generates
twin test suites for both wide::Cow and lean::Cow — 24 #[test]
functions per variant covering borrowed and owned construction,
into_owned, unwrap_borrowed (including the panic case), Clone,
Hash, ordering, From<std::borrow::Cow> round-trip, Default,
const_str/const_slice, and a stress_test_owned that drives
1024 iterations of clone+into_owned mutation (10 iterations under
Miri). The upstream ci/miri.sh script runs
cargo miri test --all-features with
-Zmiri-strict-provenance, so the unsafe paths are validated under
the strictest aliasing model on every commit. Together these justify
has-unit-tests, unsafe-tested, and datastructure-impl-tested. No
integration, fuzz, or property tests (has-integration-tests,
has-fuzz-tests, has-property-tests). datastructure-impl-bounds is
met: the documented lean::Cow 32-bit limit is the only deviation
from std::borrow::Cow's bounds and is documented at the module
level.
Conclusion
beef is a small, mature Cow replacement that uses unsafe only
where strictly necessary to round-trip a String/Vec through raw
parts. Its CI runs the suite under Miri with strict-provenance. One
low-severity correctness finding (FINDING-1) documents an
inconsistency between the owned and borrowed code paths in
lean::Cow when the length exceeds 32 bits. No security or safety
concerns were identified, justifying is-benign.