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
2 changes: 1 addition & 1 deletion quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ generic std gap is planned here even when moq never calls it.
- [References to byte arrays std takes](/quest/m3/ts-byte-refs-taken.md) - `extend` by references to arrays, adaptors' closures over held arrays, and a collection of both forms translate
- [Waiting: a slice object for a mutable part of other values](/quest/m3/ts-slice-object.md) - waits on a moq profile showing the `Proxy` view's traps matter, then decides on an `rt.ByteSlice`-like form
- [Port the workflow guard to kixelated/quest](/quest/m3/quest-workflow-guard.md) - quest's environment guard parses YAML as this repository's does
- [A deque's two slices](/quest/m3/ts-deque-slices.md) - `VecDeque::as_slices` and `{:?}` of a deque's `Iter`, `IterMut`, and `Drain` translate, split where std's are
- [Equality of Cell and RefCell](/quest/m3/ts-eq-cells.md) - `==` and `!=` of `Cell`s and `RefCell`s translate
- [Cow of a slice, and Wrapping](/quest/m3/ts-cow-slices.md) - `Cow<[T]>` and `Wrapping<T>` translate, `PartialEq` included
- [std iterators' Debug](/quest/m3/ts-iter-debug.md) - `{:?}` of std's iterators translates, writing std's text, a deque's two slices included
- [LinkedList](/quest/m3/ts-linked-list.md) - `LinkedList` and its methods translate
- [A parameter read only where lowering leaves nothing](/quest/m3/ts-unread-params.md) - an instance whose lowering drops every read of a parameter marks it unused, so `tsc` accepts it
- [Zip's next_back in constant time](/quest/m3/ts-zip-back.md) - a reversed zip of random-access iterators skips the longer side's excess at once
Expand Down
34 changes: 34 additions & 0 deletions quest/m3/ts-deque-slices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# [M] A deque's two slices

## Goal

[rust2-ts](/ts/README.md) translates `VecDeque::as_slices` and `as_mut_slices`, and `{:?}`
of `vec_deque::Iter`, `IterMut`, and `Drain`, writing the same text as std, proven by
differential tests against native Rust on wrapped deques.

## Plan

Left by [moq-dev/rust2#317](https://github.com/moq-dev/rust2/pull/317), which translated
the rest of std's iterators' `Debug`.

- `Iter` and `IterMut` write the two slices of the ring buffer as `as_slices` splits it:
`Iter([3], [1, 2])`, each half as consumed so far, the second taking the first's place
once it empties (`vec_deque/iter.rs`). The split depends on the buffer's capacity and
where its head sits.
- The runtime's deque does not split where std's does: it grows to a power of two of at
least 4 and moves its head to 0, ignores `with_capacity`, and shifts items one at a time
in `insert` and `remove`. std keeps `RawVec`'s capacity, moves the shorter segment as it
grows (`handle_capacity_increase`), and moves the shorter side in `insert`, `remove`, and
the rest. Every function that places items must place them where std's does.
- `Drain` writes its counts, `Drain(drain_len, idx, tail_len, remaining)`, which the
runtime's drain does not keep.

Public API: the translator's output.

## Required

- [The rest of std the model reaches](/quest/m2/ts-model/std-rest.md) - `VecDeque` carries std's capacity, which the split depends on

## Related

- [LinkedList](/quest/m3/ts-linked-list.md) - the other std collection whose `Debug` is still refused
3 changes: 3 additions & 0 deletions quest/m3/ts-iter-clone.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,8 @@ the maintainer's 2026-10-27 decision that rust2 aims to support all of std.
- A clone must not share state the original advances: test both read after the clone,
in turns, including partially read ones, a zip past its shorter side, and adaptors whose
closures capture values that drop.
- `Debug` of std's iterators reads what each has left through `rt.Iter.remaining()`
([#317](https://github.com/moq-dev/rust2/pull/317)), where std's iterates a clone; once
clones exist, weigh replacing `remaining()` with them.

Public API: the translator's output.
23 changes: 0 additions & 23 deletions quest/m3/ts-iter-debug.md

This file was deleted.

5 changes: 4 additions & 1 deletion ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ an `rt.ParseCharError`, `{ kind }`, its private `CharErrorKind`'s name. `==` of
and of std's errors is their derived `PartialEq`, from core's MIR, so two errors are equal
where their kinds are, private or not. `Debug` of a string or `char` escapes by
std's Unicode tables, which the runtime carries, not the engine's. `Debug` of std's
collections writes their items in the order each iterates, a hash map's or set's included. A caller prints a
collections writes their items in the order each iterates, a hash map's or set's included,
and of their iterators and `Chars` the items each has left, in std's wrapper; a deque's
`Iter` and `IterMut`, which write its buffer's two halves, and its `Drain`, which writes its
counts, are refused. A caller prints a
`printable` type as `to_string()` and `format!("{err:?}")`
would: `rt.fmtToString((f) => DecodeError.fmt$Display(err, f))` and
`rt.fmtFormat([(f) => DecodeError.fmt$Debug(err, f)])`, after
Expand Down
10 changes: 5 additions & 5 deletions ts/fixtures/lang/expected/chunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,26 +154,26 @@ export function chunks(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void {
rt.byteVecExtendFromSlice(out, rt.byteSliceFrom(pairs[rt.idx(pairs, 0)]));
rt.byteVecExtendFromSlice(out, rt.byteSliceFrom(pairs[rt.idx(pairs, 1)]));
}
const iter2: rt.Iter<rt.ByteSlice> = rt.iterMap(rt.iterSlice(pairs), rt.byteSliceFrom);
const iter2: rt.Iter<rt.ByteSlice> = rt.iterLend(rt.iterSlice(pairs), rt.byteSliceFrom);
while (true) {
const _219: rt.ByteSlice | rt.Done = iter2.next();
if (_219 === rt.DONE) {
break;
}
rt.byteVecPush(out, _219.data[_219.start] ^ _219.data[_219.start + 1]);
}
const iter3: rt.Iter<rt.ByteSlice> = rt.iterMap(rt.iterSlice(pairs), rt.byteSliceFrom);
const iter3: rt.Iter<rt.ByteSlice> = rt.iterLend(rt.iterSlice(pairs), rt.byteSliceFrom);
while (true) {
const _234: rt.ByteSlice | rt.Done = iter3.next();
if (_234 === rt.DONE) {
break;
}
_234.data[_234.start] = _234.data[_234.start + 1];
}
const copies: Uint8Array[] = rt.iterToArray(rt.iterCopied(rt.iterMap(rt.iterSlice(pairs), rt.byteSliceFrom), rt.byteSliceToArray), undefined, 2, true);
rt.iterExtendBytes(out, rt.iterChain(rt.iterMap(rt.iterMap(rt.iterSlice(pairs), rt.byteSliceFrom), (p: rt.ByteSlice): rt.u8 => {
const copies: Uint8Array[] = rt.iterToArray(rt.iterCopied(rt.iterLend(rt.iterSlice(pairs), rt.byteSliceFrom), rt.byteSliceToArray), undefined, 2, true);
rt.iterExtendBytes(out, rt.iterChain(rt.iterMap(rt.iterLend(rt.iterSlice(pairs), rt.byteSliceFrom), (p: rt.ByteSlice): rt.u8 => {
return p.data[p.start];
}), rt.iterMap(rt.iterMap(rt.iterSlice(copies), rt.byteSliceFrom), (p2: rt.ByteSlice): rt.u8 => {
}), rt.iterMap(rt.iterLend(rt.iterSlice(copies), rt.byteSliceFrom), (p2: rt.ByteSlice): rt.u8 => {
return p2.data[p2.start + 1];
})), undefined, true);
} else {
Expand Down
54 changes: 27 additions & 27 deletions ts/fixtures/lang/expected/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2137,18 +2137,18 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
if (_25 === rt.DONE) {
break;
}
putAll$u8s_Union_u8s(rt.iterMap(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_Intersection_u8s(rt.iterMap(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_Difference_u8s(rt.iterMap(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_SymmetricDifference_u8s(rt.iterMap(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putHints$u8s_Union_u8s(rt.iterMap(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_Intersection_u8s(rt.iterMap(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_Difference_u8s(rt.iterMap(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_SymmetricDifference_u8s(rt.iterMap(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
putAll$u8s_Union_u8s(rt.iterLend(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_Intersection_u8s(rt.iterLend(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_Difference_u8s(rt.iterLend(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putAll$u8s_SymmetricDifference_u8s(rt.iterLend(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom), put, out);
putHints$u8s_Union_u8s(rt.iterLend(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_Intersection_u8s(rt.iterLend(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_Difference_u8s(rt.iterLend(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
putHints$u8s_SymmetricDifference_u8s(rt.iterLend(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom), 1, out);
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.btreeUnion(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.btreeIntersection(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.btreeDifference(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.btreeSymmetricDifference(_25[0], _25[1]), rt.byteSliceFrom).next()), 221, put));
rt.iterExtendBytes(out, rt.iterSlice(Uint8Array.of(rt.btreeIsSubset(_25[0], _25[1]) ? 1 : 0, rt.btreeIsSuperset(_25[0], _25[1]) ? 1 : 0, rt.btreeIsDisjoint(_25[0], _25[1]) ? 1 : 0)), undefined, true);
const iter2: rt.Iter<rt.BTreeSet<Uint8Array>> = rt.iterSlice([rt.btreeFromSorted(rt.btreeNew(rt.cmpBytes) as rt.BTreeSet<Uint8Array>, rt.iterMap(rt.btreeUnion(_25[0], _25[1]), copy$u8s)), rt.btreeFromSorted(rt.btreeNew(rt.cmpBytes) as rt.BTreeSet<Uint8Array>, rt.iterMap(rt.btreeIntersection(_25[0], _25[1]), copy$u8s)), rt.btreeFromSorted(rt.btreeNew(rt.cmpBytes) as rt.BTreeSet<Uint8Array>, rt.iterMap(rt.btreeDifference(_25[0], _25[1]), copy$u8s)), rt.btreeFromSorted(rt.btreeNew(rt.cmpBytes) as rt.BTreeSet<Uint8Array>, rt.iterMap(rt.btreeSymmetricDifference(_25[0], _25[1]), copy$u8s))]);
while (true) {
Expand All @@ -2157,8 +2157,8 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
break;
}
const built: rt.BTreeSet<Uint8Array> = _81;
putAll$u8s_Iter_u8s(rt.iterMap(rt.btreeKeys(built), rt.byteSliceFrom), put, out);
putAll$u8s_Rev_Iter_u8s(rt.iterRev(rt.iterMap(rt.btreeKeys(built), rt.byteSliceFrom)), put, out);
putAll$u8s_Iter_u8s(rt.iterLend(rt.btreeKeys(built), rt.byteSliceFrom), put, out);
putAll$u8s_Rev_Iter_u8s(rt.iterRev(rt.iterLend(rt.btreeKeys(built), rt.byteSliceFrom)), put, out);
}
}
const _93: rt.Iter<Uint8Array> = rt.iterMap(rt.iterSlice(rt.byteSliceView(left)), (_23: rt.u8): Uint8Array => {
Expand All @@ -2175,15 +2175,15 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
if (_111 === rt.DONE) {
break;
}
putSorted$u8s(rt.iterToArray(rt.iterMap(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterMap(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterMap(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterMap(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putHints$u8s_Union_u8s_RandomState(rt.iterMap(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_Intersection_u8s_RandomState(rt.iterMap(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_Difference_u8s_RandomState(rt.iterMap(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_SymmetricDifference_u8s_RandomState(rt.iterMap(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v: rt.ByteSlice): rt.u8 => {
putSorted$u8s(rt.iterToArray(rt.iterLend(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterLend(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterLend(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterLend(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom), "next", 4), put, out);
putHints$u8s_Union_u8s_RandomState(rt.iterLend(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_Intersection_u8s_RandomState(rt.iterLend(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_Difference_u8s_RandomState(rt.iterLend(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
putHints$u8s_SymmetricDifference_u8s_RandomState(rt.iterLend(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom), 0, out);
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.hashUnion(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v: rt.ByteSlice): rt.u8 => {
let _3!: boolean;
if (!rt.hashContains(_111[0], rt.byteSliceView(v))) {
_3 = rt.hashContains(_111[1], rt.byteSliceView(v));
Expand All @@ -2192,7 +2192,7 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
}
return _3 ? 1 : 0;
}));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v2: rt.ByteSlice): rt.u8 => {
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.hashIntersection(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v2: rt.ByteSlice): rt.u8 => {
let _32!: boolean;
if (!rt.hashContains(_111[0], rt.byteSliceView(v2))) {
_32 = false;
Expand All @@ -2201,10 +2201,10 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
}
return _32 ? 1 : 0;
}));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v3: rt.ByteSlice): rt.u8 => {
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.hashDifference(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v3: rt.ByteSlice): rt.u8 => {
return !rt.hashContains(_111[1], rt.byteSliceView(v3)) ? 1 : 0;
}));
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterMap(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v4: rt.ByteSlice): rt.u8 => {
rt.byteVecPush(out, mapOr$1w1gbwl(rt.iterToOption(rt.iterLend(rt.hashSymmetricDifference(_111[0], _111[1]), rt.byteSliceFrom).next()), 221, (v4: rt.ByteSlice): rt.u8 => {
return rt.hashContains(_111[0], rt.byteSliceView(v4)) !== rt.hashContains(_111[1], rt.byteSliceView(v4)) ? 1 : 0;
}));
rt.iterExtendBytes(out, rt.iterSlice(Uint8Array.of(rt.hashIsSubset(_111[0], _111[1]) ? 1 : 0, rt.hashIsSuperset(_111[0], _111[1]) ? 1 : 0, rt.hashIsDisjoint(_111[0], _111[1]) ? 1 : 0)), undefined, true);
Expand All @@ -2214,7 +2214,7 @@ export function setOpsOf$u8s(left: rt.ByteSlice, right: rt.ByteSlice, make: (a0:
if (_175 === rt.DONE) {
break;
}
putSorted$u8s(rt.iterToArray(rt.iterMap(rt.hashKeys(_175), rt.byteSliceFrom), "next", 4), put, out);
putSorted$u8s(rt.iterToArray(rt.iterLend(rt.hashKeys(_175), rt.byteSliceFrom), "next", 4), put, out);
}
}
}
Expand Down
Loading