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
11 changes: 11 additions & 0 deletions quest/m2/ts-model/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,22 @@ refuses for good, and smallvec's union over a type parameter and raw parts (10)
[unsafe](/quest/m3/ts-unsafe.md), so both need safe `cfg(rust2_ts)` twins or bindings
there, as does the `unsafe` slice of `model/frame.rs`'s `Filled`.

Decided with the maintainer on 2026-11-04, from a census at the bumped pin
(moq-dev/rust2#390): the refusals no quest owned became the children below. ✅ arrayvec's
`ArrayString` needs three of them (const generic types, `begin_panic`, `str::as_ptr`),
kept separate since each lands alone; rejected: one quest for `ArrayString`.

## Required

- [Iterators into a crate's own collections](/quest/m2/ts-model/from-iterator.md) - `collect`, `flat_map`, and `flatten` through moq-pattern's `Patterns`
- [Bytes from an owner that drops](/quest/m2/ts-model/bytes-owner.md) - `Bytes::from_owner` of a frame's segment
- [rangemap](/quest/m2/ts-model/rangemap.md) - B-tree ranges by a borrowed key, and std's iterators in a crate's fields
- [Addresses as identity](/quest/m2/ts-model/addresses.md) - `Arc::as_ptr(a) as usize` as a key, which needs a decision
- [Option fields at a unit instance](/quest/m2/ts-model/unit-option-fields.md) - `Idle<()>`'s `Option<T>` field tells `Some(())` from `None`
- [Const generic types](/quest/m2/ts-model/const-generics.md) - `ArrayString<CAP>` and other types with const parameters
- [panic! in a 2015 or 2018 crate](/quest/m2/ts-model/begin-panic.md) - the `begin_panic` mapping keyed by its defining module
- [A string's bytes through its pointer](/quest/m2/ts-model/str-as-ptr.md) - `str::as_ptr` reads the string's UTF-8
- [Scheduler hints](/quest/m2/ts-model/scheduler-hints.md) - `thread::yield_now` and `hint::spin_loop` translate to nothing
- [Slices not yet written](/quest/m2/ts-model/uninit-slices.md) - `Box::new_uninit_slice` of a frame's segment

Public API: the translator's output for moq-net's model.
15 changes: 15 additions & 0 deletions quest/m2/ts-model/begin-panic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# [XS] panic! in a 2015 or 2018 crate

## Goal

[rust2-ts](/ts/README.md) translates `panic!("literal")` in a 2015 or 2018 edition crate,
which expands to `std::rt::begin_panic`, as it does in 2021, proven by a 2018-edition
panics fixture against native Rust. Today arrayvec's is refused.

## Plan

The mapping is keyed by `("rt", "begin_panic")`, but `library::key` builds keys from the
defining module, and std defines `begin_panic` in `std::panicking` and only re-exports it
from `rt`, so the mapping never matches. No fixture used a pre-2021 `panic!`.

Public API: the translator's output.
15 changes: 15 additions & 0 deletions quest/m2/ts-model/const-generics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# [M] Const generic types

## Goal

[rust2-ts](/ts/README.md) translates structs and enums with const parameters, such as
arrayvec's `ArrayString<CAP>` and `ArrayVec<T, N>`, so each instance's body reads its own
`N`, proven by differential tests against native Rust. At the moq pin it refuses once in
the model (`Path::join`'s `ArrayString`) and 8 times in moq-net whole.

## Plan

Functions with const parameters already translate per instance; types do not yet. Check
how the choice interacts with a type's class being shared across instances.

Public API: the translator's output.
14 changes: 14 additions & 0 deletions quest/m2/ts-model/scheduler-hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# [XS] Scheduler hints

## Goal

[rust2-ts](/ts/README.md) translates `thread::yield_now` and `hint::spin_loop` to nothing,
as neither promises anything observable, proven by a differential test against native
Rust. At the moq pin `model/frame.rs`'s `attach` refuses on `yield_now`.

## Plan

A spin loop that waits on another thread hangs natively on one thread too, so translating
the hint to nothing matches Rust.

Public API: the translator's output.
15 changes: 15 additions & 0 deletions quest/m2/ts-model/str-as-ptr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# [S] A string's bytes through its pointer

## Goal

[rust2-ts](/ts/README.md) translates `str::as_ptr` as a read-only pointer to the string's
UTF-8, so `ptr::copy_nonoverlapping` and `slice::from_raw_parts` read what Rust reads,
proven by differential tests against native Rust. At the moq pin arrayvec's
`ArrayString` refuses it once in the model and 3 times in moq-net whole.

## Plan

A `&str` stays a JS string (decided on #574), so the bytes are an encoding of it; a pointer into
them must not let a write through it go unnoticed, which Rust forbids anyway for a `&str`.

Public API: the translator's output.
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ differential tests against native Rust.
A `MaybeUninit<T>` is a `T` in JS, and one of a byte is the byte, so a `[MaybeUninit<u8>]`
is an `rs.ByteSlice`; `write_copy_of_slice` and a slice's `assume_init_ref` and
`assume_init_mut` already map. `write_clone_of_slice` clones in without dropping what was
there, unlike `clone_from_slice`. Found translating `spare_capacity_mut`; no consumer calls
either yet.
there, unlike `clone_from_slice`. Found translating `spare_capacity_mut`. moq-net's `model/frame.rs` calls
`Box::<[u8]>::new_uninit_slice` in `Segment::new` at the moq pin.
18 changes: 18 additions & 0 deletions quest/m2/ts-model/unit-option-fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# [S] Option fields of a generic type at a unit instance

## Goal

[rust2-ts](/ts/README.md) translates a generic type's `Option<T>` or `Poll<T>` field at an
instance whose `T` is itself `undefined` or pending in JS, such as moq-net's `Idle<()>`
(`util/idle.rs`'s `parked`) and tokio's `oneshot::Inner<()>`, proven by differential
tests against native Rust. At the moq pin it refuses 16 times in the model and 24 in
moq-net whole.

## Plan

The type's definition types the field `T | undefined`, which loses `Some(())` against
`None` at `T = ()`; the field needs `rs.None` (or `rs.OuterPending`) where an instance
can already be the bare value. Decide it per field from the instances the crate uses, not
per type, and keep the bare form for every other instance.

Public API: the translator's output.
2 changes: 1 addition & 1 deletion quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ generic std gap is planned here even when moq never calls it.
- [rs.Slice](/quest/m3/ts-slice-object.md) - references to arrays of other values are a runtime slice too, and pointers compare by where they point
- [Writes through iter_mut without a Place per item](/quest/m3/ts-iter-mut-places.md) - a loop over `iter_mut()` of copy values writes the slice's array by index
- [rs.String](/quest/m3/ts-string-capacity.md) - `String`, `Box<str>`, and `&str` are a runtime type holding std's capacity
- [Slices not yet written](/quest/m3/ts-uninit-slices.md) - `Box::new_uninit_slice` and `write_clone_of_slice` translate
- [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - no runtime `rust2-ts:` error where native Rust goes on: an exact slower path, or a refusal at translation
- [rust2-ts with no ts.toml](/quest/m3/ts-configless.md) - a crate's whole `pub` API translates with no config and no bound items
- [Buf on a deque of bytes](/quest/m3/ts-vecdeque-buf.md) - `bytes`' `Buf` for a deque of bytes translates
- [std's panic messages hold std's capacity](/quest/m3/ts-panic-payload-capacity.md) - a hook reads native's `String` capacity from std's own formatted panics
- [A B-tree drops as std's does](/quest/m3/ts-btree-drop-order.md) - keys and values drop node by node, in std's order
20 changes: 20 additions & 0 deletions quest/m3/ts-panic-payload-capacity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# [M] std's panic messages hold std's capacity

## Goal

A panic hook in code [rust2-ts](/ts/README.md) generates reads the same `String` capacity
from std's own formatted panic messages (such as `slice index starts at {} but ends at
{}`) as native Rust, proven by the panics fixture's hook against native Rust.

## Plan

Found in #574, which gives `String` its capacity: the runtime passes std's formatted messages as one string, so their
capacity differs from std's, which builds them piece by piece (37 against 44 for that
message). About 64 runtime sites pass such a message. Build each as std's `format!` does,
without slowing the paths that never panic.

Public API: the runtime's panic sites, not their messages.

## Required

- [rs.String](/quest/m3/ts-string-capacity.md) - `String` holds std's capacity, which a hook then reads