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
1 change: 1 addition & 0 deletions quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ generic std gap is planned here even when moq never calls it.
- [The rest of a vector's methods](/quest/m3/ts-vec-rest.md) - `append`, `resize`, `split_off`, `try_reserve`, and `Vec::from(VecDeque)` translate
- [A reversed zip's per-pair cost](/quest/m3/ts-zip-rev-overhead.md) - a reversed by-index zip costs per pair what a forward one does, or the gap is explained
- [Whole writes into a lazy cell or thread-local key](/quest/m3/ts-lazy-writes.md) - a whole write through a `&mut` to a `LazyCell`, `LazyLock`, or `LocalKey` keeps its state
- [Debug of a LazyCell or a LazyLock](/quest/m3/ts-lazy-debug.md) - `{:?}` of a `LazyCell` and a `LazyLock` writes its value or `<uninit>`, as std's do
- [Type errors at the Rust that made them](/quest/m3/ts-span-precision.md) - a `tsc` error on output names the tail expression or call argument that made it
- [An empty iterator of mutable references](/quest/m3/ts-empty-places.md) - `iter::empty::<&mut T>()` given to `zip` or `chain` translates
- [An Option of numbers in the result slot](/quest/m3/ts-option-slot.md) - `varint_opt`'s `Option` comes back through the slot with no object per call
Expand Down
4 changes: 4 additions & 0 deletions quest/m3/ts-fmt-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ difference. A writer that counts calls or fails partway, like a capped buffer, c
each run it leaves as is, empty or not, and each escape a `write_str`.
- Add `writeChar` to the runtime's `Write`, so a crate's own `write_char` override runs.
- Measure what the extra calls cost `format!` into a `String`.
- Add a differential case for `Debug` of a `Cell` into a writer that sets that cell in
`write_str`. std reads the value before writing `Cell { value: `, and
[#484](https://github.com/moq-dev/rust2/pull/484) lowers it that way, but only such a writer
can observe the order.
- Rejected: allowing placeholders with the runtime's chunking. The bytes match, but a
crate's `write_str` would see calls std doesn't make.

Expand Down
26 changes: 26 additions & 0 deletions quest/m3/ts-lazy-debug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# [XS] Debug of a LazyCell or a LazyLock

## Goal

[rust2-ts](/ts/README.md) translates `{:?}` of a `LazyCell` and a `LazyLock` as std
writes them: `LazyCell(..)` of its value once forced, or `LazyCell(<uninit>)` unpadded
before, and likewise for `LazyLock`. This is proven by differential tests against native
Rust, plain and `{:#?}`, before and after a force, including a print from within its own
initialization.

## Plan

Found after [#484](https://github.com/moq-dev/rust2/pull/484) translated `Debug` of the
other cells and locks. A probe on 2026-11-02 against `main` refused both as an
"unsupported call to `<LazyCell<..> as Debug>::fmt`".

std reads `get` without forcing. The runtime's `rt.LazyCell` keeps its value and its
initialized flag in `#private` fields, so it needs a method that reads them, as
`onceDebug` reads a one-time cell's. `LazyCell::get` and `LazyLock::get` could come with
it if that is the same method.

Public API: the translator's output.

## Related

- [Whole writes into a lazy cell or thread-local key](/quest/m3/ts-lazy-writes.md) - the same `#private` state