Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ generic std gap is planned here even when moq never calls it.
- [Relink without rebuilding](/quest/m3/relink.md) - measure upstream's skip of dependency-only rebuilds on moq's edits once it reaches nightly
- [Unsafe code the translator can model](/quest/m3/ts-unsafe.md) - a dependency using only `unsafe` the translator can model translates from source
- [The capacity of a BytesMut](/quest/m3/ts-bytes-capacity.md) - `BytesMut::capacity` and what reads it translate with `bytes`' values
- [Trait objects](/quest/m3/ts-dyn.md) - `dyn Error`, `dyn Iterator`, and `dyn Buf` translate, so a consumer neither rewrites nor binds them
- [Trait objects](/quest/m3/ts-dyn.md) - `dyn Error` and `dyn Iterator` translate, so a consumer neither rewrites nor binds them
- [bytes' Chain as a Buf object](/quest/m3/ts-buf-chain.md) - `Chain::copy_to_bytes` across both halves translates, and with it a `Chain` as a `dyn Buf`
- [A Buf object's size](/quest/m3/ts-dyn-buf-size.md) - a `dyn Buf` object holds only the methods some call dispatches to
- [by_ref of a mutable reference to an iterator](/quest/m3/ts-by-ref-place.md) - `Iterator::by_ref` of a `&mut I` in a local translates
- [mem::take as a function value](/quest/m3/ts-take-value.md) - `mem::take`, `replace`, and `swap` passed as a function value translate
- [Debug of a RefCell](/quest/m3/ts-refcell-debug.md) - `{:?}` of a `RefCell`, `Ref`, and `RefMut` translates as std's writes them
- [Placeholders written to a crate's own fmt::Write](/quest/m3/ts-fmt-calls.md) - `write!` with placeholders into a crate's own writer translates, its `write_str` seeing each call std makes
- [Waiting: drop the lang fixture's mul_add allowance](/quest/m3/ts-fma-allowance.md) - the differential fails on any `mul_add` difference again once wasm32's `fma` rounds exactly
- [Waiting: type-check in process with tsrs](/quest/m3/ts-tsrs.md) - rust2-ts checks bindings through tsrs instead of `tsc` once it is a stable library
Expand Down
17 changes: 17 additions & 0 deletions quest/m3/ts-buf-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# [S] bytes' Chain as a Buf object

## Goal

[rust2-ts](/ts/README.md) translates `copy_to_bytes` of `bytes`' `Chain` across both
halves, and with it a `Chain` coerced to `dyn Buf`, whose object holds every method,
proven by a differential test against native Rust.

## Plan

Found writing `dyn Buf`: `Chain::copy_to_bytes` puts `&mut A` and a `Take<&mut B>` into a
fresh `BytesMut::with_capacity(len)`, refused as "`BufMut::put` of `&mut Bytes`" and as a
`put` that picks its methods by a capacity nothing counts. A buffer just made with a
capacity and never split has the capacity it asked for, so `put` into it can read the
source chunk by chunk, as the crate's own `copy_to_bytes` does.

Public API: the translator's output.
15 changes: 15 additions & 0 deletions quest/m3/ts-by-ref-place.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# [S] by_ref of a mutable reference to an iterator

## Goal

[rust2-ts](/ts/README.md) translates `Iterator::by_ref` of a `&mut I` held in a local,
such as `(&mut it).by_ref()` where `it: &mut I`, advancing the iterator it points at as
std's does, proven by a differential test against native Rust.

## Plan

Found writing [`dyn Iterator`](https://github.com/moq-dev/rust2/pull/437): it fails as
"`Iterator::by_ref` with a mutable reference to a value JS copies, which its mapping would
copy", since the `&mut I` itself is an `rt.Place`.

Public API: the translator's output.
16 changes: 16 additions & 0 deletions quest/m3/ts-dyn-buf-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# [S] A Buf object's size

## Goal

[rust2-ts](/ts/README.md)'s `dyn Buf` objects hold only the methods some call dispatches
to, so each buffer coerced to one adds a few functions to the output and not all of `Buf`'s.

## Plan

Found writing `dyn Buf`: an object holds every vtable entry, as the crate's own traits'
do, so the stock fixture's six buffers add about 5,000 lines of `bytes`' provided methods
translated from MIR. A crate's calls through `dyn Buf` name the methods it needs, but an
object passed to another crate may be called by methods this one never calls, so the
set has to be the dependents' too, or each method made on first call.

Public API: the translator's output.
9 changes: 6 additions & 3 deletions quest/m3/ts-dyn.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
## Goal

[rust2-ts](/ts/README.md) translates the trait objects of std's and mapped crates' traits
that moq still refuses (`dyn Error`, `dyn Iterator`, and `dyn bytes::Buf`), and behind any
pointer std coerces to one, with Rust's dispatch and drop order, proven by differential tests against native Rust, so a consumer
that moq still refuses (`dyn Error` and `dyn Iterator`), and `dyn FusedIterator`, behind
any pointer std coerces to one, such as `&mut dyn Debug` and
`Arc<dyn Iterator>`, with Rust's dispatch and drop order, proven by differential tests against native Rust, so a consumer
neither rewrites nor binds them.

## Plan
Expand All @@ -19,7 +20,9 @@ config, so trait objects move from never to not yet.
Build the rest on those.
- `Error` needs `source` and its supertraits' `Debug` and `Display` on the object, and its
`downcast_ref` can check classes as `dyn Any`'s does; moq's are thiserror's `source`.
- `Iterator` can be an `rt.Iter`, and `bytes::Buf` the `rt.ByteSlice` it reads.
- `Iterator` can be an `rt.Iter`.
- `bytes::Buf` is an object of its methods, as the crate's own traits are, decided with the
maintainer on 2026-11-02, so it works for any implementor.
- Generic traits and associated types name their arguments in the object's type.
- `Any::type_id` and `TypeId` have no JS value yet, and an upcast to `dyn Any` would need
the class of the value's own type.
Expand Down
14 changes: 14 additions & 0 deletions quest/m3/ts-refcell-debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# [XS] Debug of a RefCell

## Goal

[rust2-ts](/ts/README.md) translates `{:?}` of a `RefCell` and its `Ref` and `RefMut`,
writing `RefCell { value: .. }` and `<borrowed>` while mutably borrowed as std's does,
proven by a differential test against native Rust.

## Plan

Found writing [`Box<dyn Debug>`](https://github.com/moq-dev/rust2/pull/445): it is an
"unsupported call to `<RefCell<Vec<u8>> as Debug>::fmt`".

Public API: the translator's output.
14 changes: 14 additions & 0 deletions quest/m3/ts-take-value.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# [XS] mem::take as a function value

## Goal

[rust2-ts](/ts/README.md) translates `std::mem::take`, `replace`, and `swap` passed as a
function value, such as `v.iter_mut().map(std::mem::take)`, as their calls do, proven by a
differential test against native Rust.

## Plan

Found writing [`dyn Iterator`](https://github.com/moq-dev/rust2/pull/437): the call maps,
but the function value is an "unsupported call to `std::mem::take::<Vec<u8>>`".

Public API: the translator's output.
17 changes: 11 additions & 6 deletions ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ as its fold ends, before what it wraps, as std's does. A `Vec`'s `drain` leaves
what precedes its range until it drops, then drops what it still holds and moves the tail
back, so one never dropped, as `mem::forget` leaves it, leaks the rest, as std's does.

A trait object of the crate's own trait, or a dependency's, behind `&`, `&mut`, `Box`, or `Arc`, is an object with
A trait object of the crate's own trait, a dependency's, or `bytes`' `Buf`, behind `&`, `&mut`, `Box`, or `Arc`, is an object with
a method for each function a call can dispatch to, its supertraits' included, named for
its trait as an impl's function is and taking what follows `self`: `shape.area$Shape()`.
The trait's module exports its type, `Shape.Shape` from `dyns.Shape.ts`, which a TS
Expand All @@ -459,7 +459,8 @@ same object. A `Box<dyn Trait>` drops what it holds through its `[Symbol.dispose
a TS caller's object may leave out. An `Arc<T>` unsized to an `Arc<dyn Trait>`, or to an
`Arc<dyn Future>`, is an `rt.ArcDyn`: the object a box of its value would be, and the
`Arc<T>` it was made from, whose one count both sides' clones and drops change, and the
last of which drops the value. `Arc::ptr_eq` compares the `Arc<T>`s.
last of which drops the value. `Arc::ptr_eq` compares the `Arc<T>`s. A `dyn Buf`'s object
holds no `chunks_vectored`, whose `IoSlice` has no JS value, so a call of it fails.

A `dyn Any` is such an object with no methods, whose class `is`, `downcast_ref`,
`downcast_mut`, and `Box`'s and `Arc`'s `downcast` check for: `a instanceof Any.of$dyns_Square ?
Expand All @@ -474,7 +475,7 @@ after the call, as an `FnOnce` closure's body drops what it owns, and a box of a
reference to one is `rt.lent` of it, which never drops it. A trait object of std's
or a mapped crate's trait other than `dyn Debug` and `dyn Display` behind `&`, `Box`,
`Arc`, or `Rc`, `dyn Future`,
`dyn Any`, and the function traits, of a generic
`dyn Any`, `dyn Buf`, and the function traits, of a generic
trait or one with an associated type, of a byte array, or behind any other pointer, such
as a `Weak` or a struct's last field, is refused, and so are an upcast to `dyn Any` and
`Any::type_id`.
Expand Down Expand Up @@ -535,11 +536,15 @@ of them:
`split_off`, `try_reclaim`, `try_unsplit`, and `spare_capacity_mut`, which read it.
- `Buf` and `BufMut` of a `Bytes`, a `BytesMut`, a `&[u8]`, and a `Vec<u8>` map: the
required methods, `has_remaining`, `copy_to_slice`, `copy_to_bytes`, each `get_` and
`put_` of an integer or a float, `put_slice`, `put_bytes`, and `put`, whose panics are
`put_` of an integer or a float, each `try_get_` of an integer of 2 to 16 bytes,
`put_slice`, `put_bytes`, and `put`, whose panics are
`bytes`'. `put` of the crate's own `Buf` into a `Vec<u8>` reads it through its methods
as `bytes` does, and into a `BytesMut` is refused, as `bytes` picks those methods by its
capacity. The provided `copy_to_bytes` of the crate's own `Buf`, whose `BytesMut` has
the capacity it asks for, reads it chunk by chunk through its methods.
the capacity it asks for, reads it chunk by chunk through its methods. The provided
`get_` and `try_get_` of an integer of 2 to 16 bytes of any other `Buf`, such as a
`Take`, read its chunk where that holds the integer, and copy it out through
`copy_to_slice` where not, as `bytes`' do.
The impls forwarding through a `&mut` or a `Box` translate from `bytes`' MIR, and the
`BufMut` methods they don't forward map as the buffer's own, but `put` and `put_bytes`,
which grow it as their provided bodies do, 64 bytes at a time once it is full. `put` of
Expand Down Expand Up @@ -846,7 +851,7 @@ they need.

Byte reinterpretation, pointer addresses, pointer arithmetic on a value JS keeps as an object (other than wrapping arithmetic on a null or dangling pointer), raw allocation, and unions whose
fields overlap in different types ([unsafe](/quest/m3/ts-unsafe.md)), and trait objects other than
`&dyn Debug`, `&dyn Display`, `dyn Future`, `dyn Any`, `dyn Fn*`, and the translated crates' traits'
`&dyn Debug`, `&dyn Display`, `dyn Future`, `dyn Any`, `dyn Fn*`, `dyn Buf`, and the translated crates' traits'
behind `&`, `&mut`, `Box`, or `Arc` ([trait objects](/quest/m3/ts-dyn.md)), fail translation. Until they translate, an item that needs one, such as a `dyn Error`, binds to
hand-written TS ([bindings](#bindings)).

Expand Down
Loading