Skip to content

view: make OwnedView::to_owned_message infallible#268

Merged
iainmcgin merged 2 commits into
mainfrom
iain/ownedview-infallible
Jul 1, 2026
Merged

view: make OwnedView::to_owned_message infallible#268
iainmcgin merged 2 commits into
mainfrom
iain/ownedview-infallible

Conversation

@iainmcgin

Copy link
Copy Markdown
Collaborator

For 0.9.0: OwnedView::to_owned_message and the generated FooOwnedView::to_owned_message become infallible, returning the owned message directly. Requested off the back of the connect-rust workstream, which currently unwraps internally so RPC handlers don't see a fallible conversion — this fixes it at the right layer.

Why this is sound

Every OwnedView constructor wire-decodes its view (decode, decode_with_options, from_owned), Clone preserves provenance (refcount bump + view copy including the conversion budget), no Deserialize/From path constructs one otherwise, and unsafe from_parts' safety contract is strengthened to require wire-decode provenance. Combined with the 0.8.1 guarantee (decode charges exactly what conversion re-materializes, and replay runs under the recorded budget and nesting depth), the Result only ever encoded an unreachable error path. A contract violation — a buggy hand-written MessageView impl, or a from_parts breach — panics with a descriptive message via a non-generic #[cold] path, pinned by a should_panic test.

The MessageView trait method deliberately stays Result: hand-written impls and push_raw-built views can legitimately fail, and a plain view type cannot carry provenance. The trait doc now cross-references the infallible sibling. The lazy family (genuinely fallible, deferred validation) is untouched.

Structure

Two commits: (1) changelog bookkeeping recording the shipped v0.8.1 maintenance release on main (adds .changes/0.8.1.md, removes the shipped #266 fragment from unreleased so 0.9.0 notes don't double-report it — also makes this PR's "since 0.8.1" citation resolvable in main's changelog); (2) the breaking change itself, with regenerated WKT + descriptor code and a Breaking changes fragment carrying explicit migration guidance (including the from_parts audit note).

Notes for review

  • cargo semver-checks -p buffa --baseline-version 0.8.1: the one failure (message_field_always_present generic-param change) is pre-existing on main; the return-type change here isn't in its lint set but is a break by inspection — hence the fragment.
  • examples/bsr-quickstart gains one more expected mismatch: it's generated by the published BSR plugin (pinned), already doesn't compile on main against the current runtime, and is workspace-excluded/non-CI. It regenerates when the 0.9.0 plugin ships — left untouched deliberately.
  • Open design note (not in this PR): connect-rust's unary path wraps a plain view and uses the fallible trait method, so it keeps one internal expect. With existing API they can hold an OwnedView via from_parts (their dispatch glue satisfies its contract exactly); a provenance-gated trait variant is the library-side alternative if we want it later.

Verified: full workspace tests, clippy (all-targets, all-features), rustdoc -D warnings on published crates, conformance 14/14, and a consumer-crate check driving the wrapper, the generic OwnedView over a 1000-record unknown-field payload, Clone provenance, the documented panic text from a downstream contract-breaking impl, the negative compile probe (trait stays Result), and the #[must_use] warning.

v0.8.1 was released from the v0.8.x branch (cut from the v0.8.0 tag, so
the unreleased breaking changes on main stay out of it). Bring main's
changelog up to date: add .changes/0.8.1.md with the released section,
fold it into CHANGELOG.md via changie merge, and remove the now-shipped
unknown-field accounting fragment from .changes/unreleased so the 0.9.0
release notes do not report the fix a second time.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

Every OwnedView constructor wire-decodes its view (decode,
decode_with_options, from_owned), and a view produced by wire decoding
always converts — since 0.8.1, decode-time unknown-field accounting
charges exactly what conversion re-materializes and conversion replays
under the recorded budget and group-nesting depth. The Result on
OwnedView::to_owned_message therefore only ever encoded an unreachable
error path, which downstream RPC glue was papering over with internal
unwraps. Drop it: the method (and the generated FooOwnedView wrapper
method) now returns the owned message directly, with #[must_use]
preserving the discarded-result lint the implicit Result used to
provide.

The MessageView trait method deliberately stays fallible: hand-written
impls and push_raw-built views can legitimately fail, and plain view
types cannot carry wire-decode provenance in their own type. The trait
doc now cross-references the infallible OwnedView sibling.

A contract violation — a buggy hand-written MessageView impl wrapped in
OwnedView, or a from_parts view without wire-decode provenance — panics
with a descriptive message via a non-generic #[cold] path (format
machinery emitted once, not per monomorphization), pinned by a
should_panic test. from_parts' safety contract is strengthened
accordingly: the view must have been produced by wire-decoding the
buffer, not merely borrow from it.

The examples/bsr-quickstart generated code intentionally lags: it is
produced by the published BSR plugin (pinned), already does not compile
on main against the current runtime, and is regenerated when the next
plugin ships.
@iainmcgin iainmcgin force-pushed the iain/ownedview-infallible branch from 729baf6 to c541146 Compare July 1, 2026 17:11
@iainmcgin iainmcgin marked this pull request as ready for review July 1, 2026 18:32
@iainmcgin iainmcgin requested a review from azdagron July 1, 2026 18:32
@iainmcgin iainmcgin added this pull request to the merge queue Jul 1, 2026
Merged via the queue into main with commit 58708d8 Jul 1, 2026
9 checks passed
@iainmcgin iainmcgin deleted the iain/ownedview-infallible branch July 1, 2026 21:51
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants