From 753c865fd53cc3bd1ca99054cda286d81ebffe63 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:13:05 -0700 Subject: [PATCH] chore(quest): plan the translator fixes the moq pin bump needs, and sessions over the C ABI #144's pin bump breaks rust2-ts on str::from_utf8 and a vec_view miscompile, so each gets an m1 quest. #150 found sessions need a transport C can't supply: bindings get moq-tokio inside first, then sans-IO QUIC. Co-Authored-By: Claude Opus 5.5 --- quest/m1/README.md | 2 ++ quest/m1/ffi-export/README.md | 2 ++ quest/m1/ffi-export/session-quic.md | 19 +++++++++++++++++++ quest/m1/ffi-export/session-tokio.md | 19 +++++++++++++++++++ quest/m1/ts-utf8.md | 20 ++++++++++++++++++++ quest/m1/ts-vec-view.md | 17 +++++++++++++++++ 6 files changed, 79 insertions(+) create mode 100644 quest/m1/ffi-export/session-quic.md create mode 100644 quest/m1/ffi-export/session-tokio.md create mode 100644 quest/m1/ts-utf8.md create mode 100644 quest/m1/ts-vec-view.md diff --git a/quest/m1/README.md b/quest/m1/README.md index f442f6c3a..ea14ef0bf 100644 --- a/quest/m1/README.md +++ b/quest/m1/README.md @@ -17,5 +17,7 @@ are folded into the [exporter's](/quest/m1/ffi-export/README.md). The ## Required - [Waiting: publish the UniFFI fork](/quest/m1/uniffi-release.md) - the fork publishes to crates.io under `rust2-*` names, once the maintainer decides it should +- [Vec views of the right type](/quest/m1/ts-vec-view.md) - rust2-ts never translates a `Vec` of non-bytes as bytes, and the exporter's pin bump unblocks +- [Strings from UTF-8 bytes](/quest/m1/ts-utf8.md) - `str::from_utf8` translates, so the translator follows moq past its owned `Path` - [Exporter](/quest/m1/ffi-export/README.md) - moq's bindings exported from its crates' `pub` API, replacing the fork - [Land main through quest land](/quest/m1/land.md) - every queued PR lands as one tested batch through the shared gate diff --git a/quest/m1/ffi-export/README.md b/quest/m1/ffi-export/README.md index d728049b2..6a76d2fc8 100644 --- a/quest/m1/ffi-export/README.md +++ b/quest/m1/ffi-export/README.md @@ -40,6 +40,8 @@ Every generator on the C ABI: - [Closures lent for the call](/quest/m1/ffi-export/lent-closures.md) - a callback borrowed for one call, as `modify`'s `Guard` needs - [One library from several crates](/quest/m1/ffi-export/crates.md) - the C names the several-crate export still can't give - [Driving sessions and origins](/quest/m1/ffi-export/driving.md) - how a binding polls moq's `Driver` +- [Sessions on moq-tokio](/quest/m1/ffi-export/session-tokio.md) - bindings connect and accept with one call, the library running moq-tokio inside +- [Sessions on sans-IO QUIC](/quest/m1/ffi-export/session-quic.md) - bindings move UDP datagrams and drive the session's poll themselves - [A contract symbol](/quest/m1/ffi-export/contract.md) - a header and a library from different builds refuse to mix - [C++ bindings](/quest/m1/ffi-export/cpp.md) - C++17, 20, and 23 over the C ABI, with native futures - [Kotlin bindings](/quest/m1/ffi-export/kotlin.md) - JNI or Panama over the C ABI, with native futures diff --git a/quest/m1/ffi-export/session-quic.md b/quest/m1/ffi-export/session-quic.md new file mode 100644 index 000000000..e22aa339c --- /dev/null +++ b/quest/m1/ffi-export/session-quic.md @@ -0,0 +1,19 @@ +# [M] Sessions on sans-IO QUIC + +## Goal + +A binding runs moq sessions over moq-quic's sans-IO QUIC with no runtime in the library: +the library owns QUIC and TLS, and the binding moves UDP datagrams and drives the session's +poll from its own event loop, as driving decided for the origin's +`Driver`. Proven from C in `moq/moq.c` against a local server. + +## Plan + +Decided with the maintainer on 2026-10-27: the full-control path, after +[sessions on moq-tokio](/quest/m1/ffi-export/session-tokio.md). It suits consumers with +their own event loop or sockets. + +- Exported from moq-quic's and moq-net's `pub` API; where moq-quic's session does not yet + fit moq-net's transport trait, that adapter is moq's change, not the exporter's. + +Public API: the C names moq's bindings get. diff --git a/quest/m1/ffi-export/session-tokio.md b/quest/m1/ffi-export/session-tokio.md new file mode 100644 index 000000000..9f36b1acd --- /dev/null +++ b/quest/m1/ffi-export/session-tokio.md @@ -0,0 +1,19 @@ +# [M] Sessions on moq-tokio + +## Goal + +A binding connects and accepts moq sessions with one call, as moq-ffi does today: the +exported library runs moq-tokio's sockets and runtime inside, and the binding never drives +a transport. Proven from C in `moq/moq.c` against a local relay or server. + +## Plan + +Decided with the maintainer on 2026-10-27, from +[#150](https://github.com/kixelated/rust2/pull/150): `Client::connect` and `Server::accept` +need a transport C can't supply. Bindings get both: this easy path first, since most +consumers want it, then [the sans-IO path](/quest/m1/ffi-export/session-quic.md). + +- The runtime inside is moq-tokio's own, exported from its `pub` API like everything else. + Where its API needs a wrapper to cross the C ABI, that wrapper is new API in moq-tokio. + +Public API: the C names moq's bindings get. diff --git a/quest/m1/ts-utf8.md b/quest/m1/ts-utf8.md new file mode 100644 index 000000000..3013ccce7 --- /dev/null +++ b/quest/m1/ts-utf8.md @@ -0,0 +1,20 @@ +# [S] Strings from UTF-8 bytes + +## Goal + +[rust2-ts](/ts/README.md) translates `std::str::from_utf8` and `Utf8Error` (its +`valid_up_to`, `error_len`, `Display`, and `Debug`), with std's results on invalid input, +proven by differential tests against native Rust. `just ts moq` passes at the moq revision +past [moq-dev/moq#6843](https://github.com/moq-dev/moq/pull/6843), whose decoder calls it. + +## Plan + +Decided with the maintainer on 2026-10-27: the exporter and the translator share one moq +pin, so [the exporter's pin bump](https://github.com/kixelated/rust2/pull/144) merges once +this and [the `Vec` view fix](/quest/m1/ts-vec-view.md) pass at its revision. + +- `TextDecoder` with `fatal` rejects what std rejects, but the error position must be std's + `valid_up_to` and `error_len`, so check its edge cases (truncated sequences, surrogates, + overlongs) against native. + +Public API: the translator's output. diff --git a/quest/m1/ts-vec-view.md b/quest/m1/ts-vec-view.md new file mode 100644 index 000000000..a472cc912 --- /dev/null +++ b/quest/m1/ts-vec-view.md @@ -0,0 +1,17 @@ +# [S] Vec views of the right type + +## Goal + +[rust2-ts](/ts/README.md)'s `vec_view` (`ts/src/lower/library.rs`) decides whether a `Vec` +is a byte vector from the `Vec`'s own type, so `Vec::as_slice` no longer panics and a +`Vec>` is never translated as bytes, proven by differential tests against native +Rust. `just ts census` passes at the moq revision +[the exporter's pin bump](https://github.com/kixelated/rust2/pull/144) moves to. + +## Plan + +Found by [#144](https://github.com/kixelated/rust2/pull/144) on 2026-10-27: the `as_slice` +case passes the element type where the `Vec` type is expected. A silent miscompile on any +pin, so reproduce it on `main` first, then find every caller that mixes the two. + +Public API: the translator's output.