Skip to content

API misuse checks compile out of release builds: the Rust check model matches the C++ reference

Choose a tag to compare

@rowan-claude rowan-claude released this 19 Aug 07:23

No wire change. Wire bytes are identical to 2.1.1, and the semver gate confirms the API is compatible.

A release build of this crate now performs the same amount of API-misuse checking the C++ library does: none. The eight hard assert! sites, plus the shared misuse macro's hard read leg, are debug_assert! (#47).

  • The read path's remaining 1.x hard panics were on invalid arguments, not on wire data: bit widths outside [1,32], min > max, buffer_size below 2, and BitReader::new given bytes beyond the buffer. Those were this port's invention. The C++ library compiles every serialize_assert out in release, read side and write side alike, so they compile out here too. Found by the 2026-08-16 six-language check-model audit (issue #45), against the family standard: "the caller is responsible for well formed writes... We want MINIMAL runtime checking in release."
  • This also closes a doc/code contradiction: the crate docs claimed the write-spine width assert was debug-only while BitWriter::new and write_bits made it hard.
  • Unchanged in every build, because these validate the wire rather than the caller: buffer-end Error::Overflow, Error::Align, Error::ValueOutOfRange, and the string and wstring content refusals. Safe Rust's own slice bounds checks also stay, the named language cost of unsafe_code = "forbid".
  • Debug builds are unaffected. Every moved check still fires under debug_assert!.

The changelog now names what shipped when

CHANGELOG.md's single Unreleased block had grown to span three tags, so anyone cutting notes from it would have re-announced shipped work. It is split at the tags it actually covers: 2.1.2, 2.1.1, and 2.1.0, whose UTF-16 code unit wstring move and reader refusals shipped on 2026-08-15 while the heading still read Unreleased.

GitHub release only: crates.io publishing is a separate, deliberate gate, unchanged.

Full changelog: v2.1.1...v2.1.2