diff --git a/quest/m3/README.md b/quest/m3/README.md index d667181aa..4a5f4974b 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -24,13 +24,13 @@ generic std gap is planned here even when moq never calls it. - [A slice of one byte behind any &mut](/quest/m3/ts-slice-of-one.md) - `slice::from_mut` and `array::from_mut` of a `&mut u8` 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 -- [An adaptor of the crate's own iterator held as a value](/quest/m3/ts-own-iter-value.md) - `map` and the other adaptors of a fieldless enum that implements `Iterator`, taken by value, translate - [Debug of std's other iterators](/quest/m3/ts-iter-source-debug.md) - `Debug` of `Once`, `Repeat`, `FromFn`, an array's `IntoIter`, and std's other iterators writes what std's does - [A vector keeps the capacity its pushes grew as it shrinks](/quest/m3/ts-vec-clear-capacity.md) - every step that drops a pushed `Vec`'s length keeps its capacity, as std guarantees - [A vector's exact capacity as it shrinks](/quest/m3/ts-vec-exact-capacity.md) - a deque made from a `Vec` splits its slices where std's does - [A B-tree's searches call Ord as std's do](/quest/m3/ts-btree-search-order.md) - a B-tree's lookups and inserts call a key's own `Ord` in std's order and number - [A slice's chunks as mutable arrays](/quest/m3/ts-slice-conversions.md) - `as_chunks_mut` and `as_rchunks_mut` translate, writes landing in the slice - [Comparing pointers to arrays of other values than bytes](/quest/m3/ts-array-ref-identity.md) - `ptr::eq` of pointers to a `[T; N]` of non-bytes translates, as a slice lends them too +- [Cow's clone_from, Reverse's clone, and Option::as_slice](/quest/m3/ts-std-stragglers.md) - three std methods still refused translate as std's behave - [The rest of a vector's methods](/quest/m3/ts-vec-rest.md) - `try_reserve`, a deque's rotations and searches, and `Vec::splice` translate - [Fresh writes beside a zipped iterator that points at a part](/quest/m3/ts-fresh-shapes.md) - zipping slots with a `Vec<[T; N]>`, `vec![row; n]`, or `copied` of what the slot holds translates - [Python's wake on the loop's own thread](/quest/m3/ffi-python-wake.md) - a wake on the event loop's thread resumes the future with no socket pair diff --git a/quest/m3/ts-own-iter-value.md b/quest/m3/ts-own-iter-value.md deleted file mode 100644 index 7596a06ec..000000000 --- a/quest/m3/ts-own-iter-value.md +++ /dev/null @@ -1,16 +0,0 @@ -# [S] An adaptor of the crate's own iterator held as a value - -## Goal - -[rust2-ts](/ts/README.md) translates an adaptor taking by value an iterator of the -crate's own whose JS value is copied, as a fieldless enum's is, such as -`Toggle::Ready.map(f)`, so its `next` reads and writes the iterator's place. Proven by -differential tests against native Rust. - -## Plan - -Found while translating `Debug` of std's adaptors: `toggle.map(|x| x)` of a fieldless -enum that implements `Iterator` fails to type-check, as `rt.iterFrom` is given the enum's -value where its `next` takes a `rt.Place`; `(&mut toggle).map(|x| x)` translates. Find -where `into_iter` of an owned iterator of the crate's own makes its source, and give it -the place its `next` reads through. diff --git a/quest/m3/ts-std-stragglers.md b/quest/m3/ts-std-stragglers.md new file mode 100644 index 000000000..bd38c3e9e --- /dev/null +++ b/quest/m3/ts-std-stragglers.md @@ -0,0 +1,23 @@ +# [S] Cow's clone_from, Reverse's clone, and Option::as_slice + +## Goal + +[rust2-ts](/ts/README.md) translates `Cow<[T]>::clone_from`, `Clone` of `cmp::Reverse`, +and `Option::as_slice`, each as std's behaves, proven by differential tests against +native Rust. + +## Plan + +Found while keeping a `Vec`'s capacity through `clone_from` +([#533](https://github.com/moq-dev/rust2/pull/533)): each is refused with its span today. + +- `Cow<[T]>::clone_from` of an owned `Cow` over an owned one keeps the target's buffer, + as `Vec::clone_from` does, so its capacity shows the difference from a fresh clone. +- `Reverse::clone` clones what it wraps, which may be a value that drops or one JS + shares, such as a `Vec`. +- `Option::as_slice` lends the payload as a slice of zero or one element; whether a + payload JS copies needs a place to lend it from, as `slice::from_ref` does, is open. + +No consumer calls them yet; they are planned as part of std. + +Public API: the translator's output. diff --git a/ts/README.md b/ts/README.md index 8f940ee36..85c11088b 100644 --- a/ts/README.md +++ b/ts/README.md @@ -325,7 +325,9 @@ and of one it owns, not borrows by `&mut` or boxes, its own `fold`, `rfold`, `co `find`, `rfind`, `find_map`, `for_each`, `reduce`, `all`, and `is_sorted_by`, where std's adaptors and consumers call them: a filter's `next` calls `find`, an `extend` into a hash or B-tree collection, a `String`, or a tuple calls `for_each`, `max` calls `reduce`, and -`is_sorted` calls `is_sorted_by`, which calls `all`. Its +`is_sorted` calls `is_sorted_by`, which calls `all`. One whose JS value is copied, such as an +enum's, it holds as an `rt.Place` of its own, which its `next` and std's methods taking +`&mut self` write through, as they do the place a `&mut` to it is. Its own `collect` into a `Vec` runs where std's `FromIterator` of a `Box<[T]>`, `Rc<[T]>`, `Arc<[T]>`, `BTreeMap`, `BTreeSet`, or `BinaryHeap` calls it first, its own `eq` and `partial_cmp` where `ne` and the tests on `partial_cmp` call them, and its own `by_ref`, diff --git a/ts/fixtures/lang/ends/expected/ends.ts b/ts/fixtures/lang/ends/expected/ends.ts index dc5be8c7a..a2ef0fba2 100644 --- a/ts/fixtures/lang/ends/expected/ends.ts +++ b/ts/fixtures/lang/ends/expected/ends.ts @@ -455,7 +455,7 @@ export function consumed$ends_Overrides(it: Overrides.Overrides, pick: rt.u8, k: const _28: rt.usize = rt.max(k, 1); rt.iterExtendBytes(out, rt.iterRev(rt.iterStepBy(rt.iterFrom(_27, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), _28)), "next"); } else if (pick === 7) { - put(out, option_map$05nbzug(rt.iterRposition(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), (b8: rt.u8): boolean => { + put(out, option_map$05nbzug(rt.iterRposition(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), (b8: rt.u8): boolean => { return rt.u8Rem(b8, 3) === 0; }), (i3: rt.usize): rt.u8 => { return i3 & 0xff; @@ -1386,7 +1386,7 @@ export function folded$ends_Overrides(it: Overrides.Overrides, pick: rt.u8, k: r if (!(rt.usizeRem(k, 4) === 0)) { if (!(rt.usizeRem(k, 4) === 2)) { if (!(rt.usizeRem(k, 4) === 3)) { - const r2: rt.u8 | undefined | rt.None = rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), undefined as rt.u8 | undefined, (a14: rt.u8 | undefined, b20: rt.u8): rt.u8 | undefined | rt.None => { + const r2: rt.u8 | undefined | rt.None = rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), undefined as rt.u8 | undefined, (a14: rt.u8 | undefined, b20: rt.u8): rt.u8 | undefined | rt.None => { const _416: rt.u8 = rt.u8Rem(b20, 3); if (_416 === 0) { return rt.None; @@ -1409,21 +1409,21 @@ export function folded$ends_Overrides(it: Overrides.Overrides, pick: rt.u8, k: r rt.byteVecPush(out, b19); }); }; - rt.byteVecPush(out, rt.iterTryForEach(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), _38, true, undefined, rt.None) !== rt.None ? 1 : 0); + rt.byteVecPush(out, rt.iterTryForEach(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), _38, true, undefined, rt.None) !== rt.None ? 1 : 0); rt.iterExtendBytes(out, rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), "next"); } } else { const _29: (a0: rt.u8, a1: rt.u8) => rt.u8 | undefined = (a13: rt.u8, b18: rt.u8): rt.u8 | undefined => { return thenSome$0d5am30(b18 !== rt.u8Div(k8, 4), a13 ^ b18); }; - put(out, rt.iterTryFold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), 0, _29, true)); + put(out, rt.iterTryFold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), 0, _29, true)); rt.iterExtendBytes(out, rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), "next"); } } else { const _19: (a0: rt.u8, a1: rt.u8) => rt.u8 | undefined = (a12: rt.u8, b17: rt.u8): rt.u8 | undefined => { return thenSome$0d5am30(b17 !== k8, a12 ^ b17); }; - put(out, rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), 0, _19, true)); + put(out, rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), 0, _19, true)); rt.iterExtendBytes(out, rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), "next"); } } else if (pick === 3) { @@ -1434,7 +1434,7 @@ export function folded$ends_Overrides(it: Overrides.Overrides, pick: rt.u8, k: r } return rt.Err(b16); }; - r3 = rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), 0, _60); + r3 = rt.iterTryRfold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), 0, _60); } else { const _63: (a0: rt.u8, a1: rt.u8) => rt.Result = (a10: rt.u8, b15: rt.u8): rt.Result => { if (!(rt.u8Rem(b15, 4) === rt.u8Rem(k8, 4))) { @@ -1442,7 +1442,7 @@ export function folded$ends_Overrides(it: Overrides.Overrides, pick: rt.u8, k: r } return rt.Err(b15); }; - r3 = rt.iterTryFold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), fold: Overrides.fold$iter_Iterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, count: Overrides.count$iter_Iterator, last: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.last$iter_Iterator(it)), find: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.find$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)), findMap: Overrides.findMap$iter_Iterator_u32_boxed_Box_dyn_ops_FnMut_tuple1_u8_Option_u32, forEach: Overrides.forEach$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_unit, reduce: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.reduce$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_u8_u8_u8(it, f)), all: Overrides.all$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple1_u8_bool, isSortedBy: Overrides.isSortedBy$iter_Iterator_boxed_Box_dyn_ops_FnMut_tuple2_ref_u8_ref_u8_bool, back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)), rfold: Overrides.rfold$iter_DoubleEndedIterator_Option_u32_boxed_Box_dyn_ops_FnMut_tuple2_Option_u32_u8_Option_u32, rfind: (it: Overrides.Overrides, f) => rt.iterFromOption(Overrides.rfind$iter_DoubleEndedIterator_boxed_Box_dyn_ops_FnMut_tuple1_ref_u8_bool(it, f)) }), 0, _63); + r3 = rt.iterTryFold(rt.iterFrom(it, Overrides.next$iter_Iterator, undefined, { hint: Overrides.sizeHint$iter_Iterator, nth: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nth$iter_Iterator(it, n)), back: (it: Overrides.Overrides) => rt.iterFromOption(Overrides.nextBack$iter_DoubleEndedIterator(it)), nthBack: (it: Overrides.Overrides, n) => rt.iterFromOption(Overrides.nthBack$iter_DoubleEndedIterator(it, n)) }), 0, _63); } if (r3.ok) { _66 = Uint8Array.of(0, r3.value); diff --git a/ts/fixtures/lang/iters/expected/core/option.ts b/ts/fixtures/lang/iters/expected/core/option.ts index 510d2734c..eadc72b5d 100644 --- a/ts/fixtures/lang/iters/expected/core/option.ts +++ b/ts/fixtures/lang/iters/expected/core/option.ts @@ -97,6 +97,13 @@ export function map$0p22lts(self: rt.u8 | undefined, f: (a0: rt.u8) => undefined return undefined; } +export function map$05nbzug(self: rt.usize | undefined, f: (a0: rt.usize) => rt.u8): rt.u8 | undefined { + if (self === undefined) { + return undefined; + } + return f(self); +} + export function mapOr$0lcrgk1(self: string | undefined, default_: rt.u8, f: (a0: string) => rt.u8): rt.u8 { if (self === undefined) { return default_; diff --git a/ts/fixtures/lang/iters/expected/iters.Bag.ts b/ts/fixtures/lang/iters/expected/iters.Bag.ts new file mode 100644 index 000000000..e7c80e467 --- /dev/null +++ b/ts/fixtures/lang/iters/expected/iters.Bag.ts @@ -0,0 +1,18 @@ +// Generated by rust2-ts. Do not edit. + +import * as rt from "./rt.ts"; +import * as Phase from "./iters.Phase.ts"; + +/** A pair that iterates as a `Phase` from each. */ +export interface Bag { + _0: rt.u8; + _1: rt.u8; +} + +export function intoIter$iter_IntoIterator(self: Bag): rt.Iter { + const _2: Phase.Phase = Phase.of(self._0); + const _4: Phase.Phase = Phase.of(self._1); + return rt.iterChain(rt.iterFrom({ v: _2 }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.iterFrom({ v: _4 }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) })); +} + +//# sourceMappingURL=iters.Bag.ts.map diff --git a/ts/fixtures/lang/iters/expected/iters.Logged.ts b/ts/fixtures/lang/iters/expected/iters.Logged.ts new file mode 100644 index 000000000..09d1908e5 --- /dev/null +++ b/ts/fixtures/lang/iters/expected/iters.Logged.ts @@ -0,0 +1,35 @@ +// Generated by rust2-ts. Do not edit. + +import * as rt from "./rt.ts"; + +/** A struct that logs what it has left as it drops. */ +export class Logged { + left: rt.u8; + log: rt.RefCell; + + constructor(left: rt.u8, log: rt.RefCell) { + this.left = left; + this.log = log; + } + + [Symbol.dispose](): void { + drop$ops_Drop(this); + } +} + +export function next$iter_Iterator(self: Logged): rt.u8 | rt.Done { + const _2: rt.u8 | undefined = rt.u8CheckedSub(self.left, 1); + if (_2 !== undefined) { + self.left = _2; + return rt.u8Add(self.left, 64); + } + return rt.DONE; +} + +export function drop$ops_Drop(self: Logged): void { + const _5: rt.RefCell = rt.refCellBorrowMut(self.log); + rt.byteVecPush(_5.value, 128 | self.left); + rt.refMutRelease(_5); +} + +//# sourceMappingURL=iters.Logged.ts.map diff --git a/ts/fixtures/lang/iters/expected/iters.Noted.ts b/ts/fixtures/lang/iters/expected/iters.Noted.ts new file mode 100644 index 000000000..07a5bc63d --- /dev/null +++ b/ts/fixtures/lang/iters/expected/iters.Noted.ts @@ -0,0 +1,26 @@ +// Generated by rust2-ts. Do not edit. + +import * as rt from "./rt.ts"; + +/** What logs a byte as it drops. */ +export class Noted { + _0: rt.RefCell; + _1: rt.u8; + + constructor(_0: rt.RefCell, _1: rt.u8) { + this._0 = _0; + this._1 = _1; + } + + [Symbol.dispose](): void { + drop$ops_Drop(this); + } +} + +export function drop$ops_Drop(self: Noted): void { + const _5: rt.RefCell = rt.refCellBorrowMut(self._0); + rt.byteVecPush(_5.value, self._1); + rt.refMutRelease(_5); +} + +//# sourceMappingURL=iters.Noted.ts.map diff --git a/ts/fixtures/lang/iters/expected/iters.Phase.ts b/ts/fixtures/lang/iters/expected/iters.Phase.ts new file mode 100644 index 000000000..46e1ff25e --- /dev/null +++ b/ts/fixtures/lang/iters/expected/iters.Phase.ts @@ -0,0 +1,60 @@ +// Generated by rust2-ts. Do not edit. + +import * as rt from "./rt.ts"; +import { thenSome$0d5am30 } from "./core/bool.ts"; + +/** A countdown whose JS value is a string: each step a variant. */ +export type Phase = "Three" | "Two" | "One" | "Done"; + +export function of(b: rt.u8): Phase { + const _7: rt.usize = rt.u8Rem(b, 4) as rt.usize; + if (!(_7 < 4)) { + rt.panic("index out of bounds: the len is " + 4 + " but the index is " + _7); + } + return ["Three" as Phase, "Two" as Phase, "One" as Phase, "Done" as Phase][_7]; +} + +export function left(self: Phase): rt.u8 { + if (self === "Three") { + return 3; + } + if (self === "Two") { + return 2; + } + if (self === "One") { + return 1; + } + return 0; +} + +export function next$iter_Iterator(self: rt.Place): rt.u8 | rt.Done { + let _4!: Phase; + const left_: rt.u8 = left(self.v); + if (self.v === "Three") { + _4 = "Two" as Phase; + } else if (self.v === "Two") { + _4 = "One" as Phase; + } else { + _4 = "Done" as Phase; + } + self.v = _4; + return rt.iterFromOption(thenSome$0d5am30(left_ !== 0, left_)); +} + +export function sizeHint$iter_Iterator(self: Phase): [rt.usize, rt.usize | undefined] { + const left_: rt.usize = left(self) as rt.usize; + return [left_, left_] as [rt.usize, rt.usize | undefined]; +} + +export function count$iter_Iterator(self: Phase): rt.usize { + return rt.usizeAdd(left(self) as rt.usize, 10); +} + +/** From the back, it counts up, ending where the front would. */ +export function nextBack$iter_DoubleEndedIterator(self: rt.Place): rt.u8 | undefined { + const left_: rt.u8 = left(self.v); + self.v = of(rt.u8Add(rt.u8Sub(4, rt.min(left_, 3)), 1)); + return thenSome$0d5am30(left_ !== 0, rt.u8Sub(4, left_)); +} + +//# sourceMappingURL=iters.Phase.ts.map diff --git a/ts/fixtures/lang/iters/expected/iters.Ticks.ts b/ts/fixtures/lang/iters/expected/iters.Ticks.ts new file mode 100644 index 000000000..ffe67f56a --- /dev/null +++ b/ts/fixtures/lang/iters/expected/iters.Ticks.ts @@ -0,0 +1,28 @@ +// Generated by rust2-ts. Do not edit. + +import * as rt from "./rt.ts"; +import { drop$iters_Ticks } from "./lib.ts"; +import type * as Noted from "./iters.Noted.ts"; + +/** + * An enum with a field, whose JS value is an object a `&mut` replaces, and which drops + * what it holds. + */ +export type Ticks = { tag: "Left"; _0: rt.u8; _1: Noted.Noted } | { tag: "Done" }; + +export function next$iter_Iterator(self: rt.Place): rt.u8 | rt.Done { + if (self.v.tag === "Left") { + if (self.v._0 === 0) { + self.v._1._1 = rt.u8Add(self.v._1._1, 1); + drop$iters_Ticks(self.v); + self.v = { tag: "Done" } as Ticks; + return rt.DONE; + } + self.v._0 = rt.u8Sub(self.v._0, 1); + self.v._1._1 = rt.u8Add(self.v._1._1, 1); + return self.v._0; + } + return rt.DONE; +} + +//# sourceMappingURL=iters.Ticks.ts.map diff --git a/ts/fixtures/lang/iters/expected/iters.ts b/ts/fixtures/lang/iters/expected/iters.ts index 36f3acddc..2a1745387 100644 --- a/ts/fixtures/lang/iters/expected/iters.ts +++ b/ts/fixtures/lang/iters/expected/iters.ts @@ -1,11 +1,12 @@ // Generated by rust2-ts. Do not edit. import * as rt from "./rt.ts"; -import { of$u8 } from "./lib.ts"; +import { drop$iters_Ticks, of$u8 } from "./lib.ts"; import { thenSome$185ufyt, thenSome$0b23a33, thenSome$0d5am30, thenSome$1j8foe9 } from "./core/bool.ts"; -import { unwrapOr$0k15iai as option_unwrapOr$0k15iai, unwrapOr$00uis1j as option_unwrapOr$00uis1j, unwrapOr$0r2bmpr as option_unwrapOr$0r2bmpr, unwrapOr$14m5xjm as option_unwrapOr$14m5xjm, unwrapOr$1tvry1i as option_unwrapOr$1tvry1i, unwrapOrDefault$165pyh5 as option_unwrapOrDefault$165pyh5, unwrapOrDefault$0wx44sw as option_unwrapOrDefault$0wx44sw, map$1uo1d4o as option_map$1uo1d4o, map$1httady as option_map$1httady, map$0of9gds as option_map$0of9gds, map$1c7zybz as option_map$1c7zybz, map$0cs071d as option_map$0cs071d, map$0p22lts as option_map$0p22lts, mapOr$0lcrgk1 as option_mapOr$0lcrgk1, mapOr$1kiffmd as option_mapOr$1kiffmd, mapOr$1a3irjf as option_mapOr$1a3irjf, mapOr$0sl5app as option_mapOr$0sl5app, mapOr$0atjiti as option_mapOr$0atjiti, mapOr$0okqj9y as option_mapOr$0okqj9y, mapOr$1e4a1e0 as option_mapOr$1e4a1e0, mapOr$1lznlgz as option_mapOr$1lznlgz, mapOr$0tmtgfi as option_mapOr$0tmtgfi, mapOr$0ev76sb as option_mapOr$0ev76sb, mapOr$1surhce as option_mapOr$1surhce, mapOr$1t0muvr as option_mapOr$1t0muvr, mapOr$0a96v80 as option_mapOr$0a96v80, mapOr$1vjqo89 as option_mapOr$1vjqo89, mapOr$1h04da8 as option_mapOr$1h04da8, mapOr$0f73bb7 as option_mapOr$0f73bb7, mapOr$0mmpeqx as option_mapOr$0mmpeqx, mapOr$06gg5x7 as option_mapOr$06gg5x7, mapOr$1dmz9kd as option_mapOr$1dmz9kd, mapOr$1sxa8ki as option_mapOr$1sxa8ki, mapOr$02k4ito as option_mapOr$02k4ito, asDeref$0w8at8i as option_asDeref$0w8at8i, filter$0v80fk8 } from "./core/option.ts"; +import { unwrapOr$0k15iai as option_unwrapOr$0k15iai, unwrapOr$00uis1j as option_unwrapOr$00uis1j, unwrapOr$0r2bmpr as option_unwrapOr$0r2bmpr, unwrapOr$14m5xjm as option_unwrapOr$14m5xjm, unwrapOr$1tvry1i as option_unwrapOr$1tvry1i, unwrapOrDefault$165pyh5 as option_unwrapOrDefault$165pyh5, unwrapOrDefault$0wx44sw as option_unwrapOrDefault$0wx44sw, map$1uo1d4o as option_map$1uo1d4o, map$1httady as option_map$1httady, map$0of9gds as option_map$0of9gds, map$1c7zybz as option_map$1c7zybz, map$0cs071d as option_map$0cs071d, map$0p22lts as option_map$0p22lts, map$05nbzug as option_map$05nbzug, mapOr$0lcrgk1 as option_mapOr$0lcrgk1, mapOr$1kiffmd as option_mapOr$1kiffmd, mapOr$1a3irjf as option_mapOr$1a3irjf, mapOr$0sl5app as option_mapOr$0sl5app, mapOr$0atjiti as option_mapOr$0atjiti, mapOr$0okqj9y as option_mapOr$0okqj9y, mapOr$1e4a1e0 as option_mapOr$1e4a1e0, mapOr$1lznlgz as option_mapOr$1lznlgz, mapOr$0tmtgfi as option_mapOr$0tmtgfi, mapOr$0ev76sb as option_mapOr$0ev76sb, mapOr$1surhce as option_mapOr$1surhce, mapOr$1t0muvr as option_mapOr$1t0muvr, mapOr$0a96v80 as option_mapOr$0a96v80, mapOr$1vjqo89 as option_mapOr$1vjqo89, mapOr$1h04da8 as option_mapOr$1h04da8, mapOr$0f73bb7 as option_mapOr$0f73bb7, mapOr$0mmpeqx as option_mapOr$0mmpeqx, mapOr$06gg5x7 as option_mapOr$06gg5x7, mapOr$1dmz9kd as option_mapOr$1dmz9kd, mapOr$1sxa8ki as option_mapOr$1sxa8ki, mapOr$02k4ito as option_mapOr$02k4ito, asDeref$0w8at8i as option_asDeref$0w8at8i, filter$0v80fk8 } from "./core/option.ts"; import { unwrapOr$01jdcm7 as result_unwrapOr$01jdcm7 } from "./core/result.ts"; import type * as Badge from "./iters.Badge.ts"; +import * as Bag from "./iters.Bag.ts"; import * as Bumped from "./iters.Bumped.ts"; import * as Countdown from "./iters.Countdown.ts"; import * as Doubled from "./iters.Doubled.ts"; @@ -13,8 +14,12 @@ import * as Evens from "./iters.Evens.ts"; import * as Gaps from "./iters.Gaps.ts"; import * as Halving from "./iters.Halving.ts"; import * as Held from "./iters.Held.ts"; +import * as Logged from "./iters.Logged.ts"; +import * as Noted from "./iters.Noted.ts"; +import * as Phase from "./iters.Phase.ts"; import * as Quarter from "./iters.Quarter.ts"; import * as Tag from "./iters.Tag.ts"; +import * as Ticks from "./iters.Ticks.ts"; import * as Tilt from "./iters.Tilt.ts"; import * as Weighed from "./iters.Weighed.ts"; import * as Wrapper from "./iters.Wrapper.ts"; @@ -11493,4 +11498,169 @@ export function halves$mut_iter_Copied_slice_Iter_u8(it: rt.Iter, n: rt.u return rt.byteSlicesJoin([rt.iterToByteVec(rt.iterTake(rt.iterBorrow(it), n), undefined, true), rt.iterToByteVec(rt.iterTake(rt.iterBorrow(it), 1), undefined, true)], undefined, rt.byteVecSlice); } +/** + * The crate's own iterators taken by value, whose JS value is copied as an enum's is or + * shared as a struct's is, through adaptors, consumers, `for`, and `IntoIterator`, with + * what each drops logged where it drops. + */ +export function byValue(kind: rt.u8, data: rt.ByteSlice, out: rt.ByteVec): void { + let it!: rt.Peekable; + const log: rt.RefCell = new rt.RefCell(new rt.ByteVec()); + const at: (a0: rt.usize) => rt.u8 = (i: rt.usize): rt.u8 => { + return option_unwrapOr$0r2bmpr(rt.byteSliceGet(data, i), 0); + }; + const phase: Phase.Phase = Phase.of(at(0)); + const ticks: () => Ticks.Ticks = (): Ticks.Ticks => { + return { tag: "Left", _0: rt.u8Rem(at(1), 6), _1: new Noted.Noted(log, 208) } as Ticks.Ticks; + }; + const logged: () => Logged.Logged = (): Logged.Logged => { + return new Logged.Logged(rt.u8Rem(at(2), 5), log); + }; + b0: { + const _18: rt.u8 = rt.u8Rem(kind, 13); + if (_18 === 0) { + rt.iterExtendBytes(out, rt.iterMap(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), (n14: rt.u8): rt.u8 => { + return rt.u8Mul(n14, 3); + }), "next"); + } else if (_18 === 1) { + rt.iterExtendBytes(out, rt.byteVecIntoIter(rt.iterToByteVec(rt.iterFilter(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), (n13: rt.u8): boolean => { + return rt.u8Rem(n13, 2) === 0; + }), "next")), undefined, true); + } else if (_18 === 2) { + const _26: Ticks.Ticks = ticks(); + rt.iterExtendBytes(out, rt.iterMap(rt.iterZip(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.iterFrom({ v: _26 }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v))), (_215: [rt.u8, rt.u8]): rt.u8 => { + return _215[0] ^ _215[1]; + }), "next"); + } else if (_18 === 3) { + const _30: Ticks.Ticks = ticks(); + const _32: Logged.Logged = logged(); + rt.iterExtendBytes(out, rt.iterMap(rt.iterZip(rt.iterFrom({ v: _30 }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v)), rt.iterFrom(_32, Logged.next$iter_Iterator, rt.drop)), (_214: [rt.u8, rt.u8]): rt.u8 => { + return rt.u8Add(_214[0], _214[1]); + }), "next"); + } else if (_18 === 4) { + const _36: Ticks.Ticks = ticks(); + rt.iterExtendBytes(out, rt.iterChain(rt.iterChain(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.iterFrom({ v: _36 }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v))), rt.iterFrom(logged(), Logged.next$iter_Iterator, rt.drop)), "next"); + } else { + if (_18 === 5) { + let iter: Ticks.Ticks = ticks(); + while (true) { + const _44: rt.u8 | rt.Done = Ticks.next$iter_Iterator(rt.place(() => iter, (value11) => iter = value11)); + if (_44 === rt.DONE) { + break; + } + const n: rt.u8 = _44; + const _51: rt.RefCell = rt.refCellBorrowMut(log); + rt.byteVecPush(_51.value, n); + rt.refMutRelease(_51); + } + drop$iters_Ticks(iter); + let iter2: Phase.Phase = phase; + while (true) { + const _55: rt.u8 | rt.Done = Phase.next$iter_Iterator(rt.place(() => iter2, (value12) => iter2 = value12)); + if (_55 === rt.DONE) { + break b0; + } + rt.byteVecPush(out, _55); + } + } + if (_18 === 6) { + rt.byteVecPush(out, Phase.count$iter_Iterator(phase) & 0xff); + rt.byteVecPush(out, option_unwrapOr$0r2bmpr(rt.ownedLast(rt.iterFrom({ v: Phase.of(at(1)) }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) })), 238)); + rt.byteVecPush(out, rt.iterFold(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), 1, (acc: rt.u8, n12: rt.u8): rt.u8 => { + return acc ^ n12; + }, true)); + rt.byteVecPush(out, Phase.sizeHint$iter_Iterator(phase)[0] & 0xff); + rt.byteVecPush(out, option_unwrapOr$0r2bmpr(rt.iterToOption(rt.iterRev(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) })).next()), 238)); + } else if (_18 === 7) { + rt.byteVecPush(out, rt.ownedCount(rt.iterFrom({ v: ticks() }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v))) & 0xff); + rt.byteVecPush(out, option_unwrapOr$0r2bmpr(rt.ownedLast(rt.iterFrom({ v: ticks() }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v))), 238)); + rt.byteVecPush(out, rt.iterSum(rt.iterFrom({ v: ticks() }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v)), rt.u8Add, 0, true)); + let _100: Ticks.Ticks = ticks(); + rt.byteVecPush(out, option_unwrapOr$0r2bmpr(rt.iterNth(rt.iterFrom(rt.place(() => _100, (value10) => _100 = value10), Ticks.next$iter_Iterator), 1), 238)); + drop$iters_Ticks(_100); + rt.byteVecPush(out, rt.ownedCount(rt.iterTake(rt.iterFrom(logged(), Logged.next$iter_Iterator, rt.drop), 2)) & 0xff); + } else if (_18 === 8) { + const v2: rt.ByteVec = rt.byteVecFrom(Uint8Array.of(at(3))); + const _115: Ticks.Ticks = ticks(); + rt.iterExtendBytes(v2, rt.iterFrom({ v: _115 }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v)), "next"); + rt.iterExtendBytes(v2, rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), "next"); + rt.iterExtendBytes(out, rt.byteVecIntoIter(v2), undefined, true); + } else if (_18 === 9) { + const bag: Bag.Bag = { _0: at(0), _1: at(1) }; + const iter3: rt.Iter = Bag.intoIter$iter_IntoIterator(bag); + while (true) { + const _130: rt.u8 | rt.Done = iter3.next(); + if (_130 === rt.DONE) { + break; + } + rt.byteVecPush(out, _130); + } + rt.iterExtendBytes(out, rt.iterMap(rt.iterEnumerate(rt.iterMap(Bag.intoIter$iter_IntoIterator(bag), (n10: rt.u8): rt.u8 => { + return rt.u8Add(n10, 1); + })), (_210: [rt.usize, rt.u8]): rt.u8 => { + return (_210[0] & 0xff) ^ _210[1]; + }), "next"); + } else if (_18 === 10) { + it = rt.iterPeekable(rt.iterMap(rt.iterFrom({ v: ticks() }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v)), (n9: rt.u8): rt.u8 => { + return rt.u8Mul(n9, 2); + })); + rt.iterExtendBytes(out, rt.iterOption(rt.iterToOption(it.next())), undefined, true); + rt.iterExtendBytes(out, rt.iterOption(rt.peekablePeek(it)), undefined, true); + rt.drop(it); + const _155: Logged.Logged = logged(); + const _157: Ticks.Ticks = ticks(); + const it2: rt.Iter = rt.iterSkip(rt.iterChain(rt.iterFrom(_155, Logged.next$iter_Iterator, rt.drop), rt.iterFrom({ v: _157 }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v))), 1); + rt.iterExtendBytes(out, rt.iterOption(rt.iterToOption(it2.next())), undefined, true); + const _165: rt.RefCell = rt.refCellBorrowMut(log); + rt.byteVecPush(_165.value, 170); + rt.refMutRelease(_165); + rt.drop(it2); + } else if (_18 === 11) { + const _169: rt.Iter = rt.iterRev(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) })); + for (const _172 of rt.iterToArray(rt.iterZip(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), _169), "next", 2)) { + rt.byteVecPush(out, rt.u8Add(rt.u8Mul(_172[0], 16), _172[1])); + } + rt.byteVecPush(out, option_unwrapOr$0r2bmpr(rt.iterMax(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.lt, true), 238)); + const _188: Phase.Phase = Phase.of(at(1)); + rt.byteVecPush(out, rt.iterEq(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.iterFrom({ v: _188 }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), rt.same, undefined, true, true) ? 1 : 0); + rt.iterExtendBytes(out, rt.iterTake(rt.iterCycle(rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), { v: (it: rt.Place) => ({ v: it.v }) }), rt.u8Rem(at(1), 8) as rt.usize), "next"); + } else { + let p: Phase.Phase = phase; + rt.iterExtendBytes(out, rt.iterOption(rt.iterNth(rt.iterFrom(rt.place(() => p, (value) => p = value), Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), 0)), undefined, true); + rt.byteVecPush(out, rt.iterAny(rt.iterFrom(rt.place(() => p, (value2) => p = value2), Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), (n5: rt.u8): boolean => { + return n5 === 1; + }) ? 1 : 0); + rt.iterExtendBytes(out, rt.iterTake(rt.iterMap(rt.iterFrom(rt.place(() => p, (value3) => p = value3), Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), (n6: rt.u8): rt.u8 => { + return rt.u8Add(n6, 16); + }), 1), "next"); + rt.byteVecPush(out, rt.iterFrom(rt.place(() => p, (value4) => p = value4), Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }).sizeHint()[0] & 0xff); + const _224: rt.u8 | rt.Done = Phase.next$iter_Iterator(rt.place(() => p, (value5) => p = value5)); + if (_224 !== rt.DONE) { + rt.byteVecPush(out, _224); + } + const lent: rt.Place = rt.place(() => p, (value6) => p = value6); + rt.iterExtendBytes(out, rt.iterOption(rt.iterNth(rt.iterFrom(lent, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), 0)), undefined, true); + rt.byteVecPush(out, rt.iterFrom(lent, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }).sizeHint()[0] & 0xff); + rt.iterExtendBytes(out, rt.iterFrom({ v: p }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) }), "next"); + let t: Ticks.Ticks = ticks(); + rt.iterExtendBytes(out, rt.iterOption(rt.iterFind(rt.iterFrom(rt.place(() => t, (value7) => t = value7), Ticks.next$iter_Iterator), (n7: rt.u8): boolean => { + return rt.u8Rem(n7, 2) === 0; + })), undefined, true); + rt.iterExtendBytes(out, rt.iterOption(option_map$05nbzug(rt.iterPosition(rt.iterFrom(rt.place(() => t, (value8) => t = value8), Ticks.next$iter_Iterator), (n8: rt.u8): boolean => { + return n8 === 0; + }), (i2: rt.usize): rt.u8 => { + return i2 & 0xff; + })), undefined, true); + rt.iterExtendBytes(out, rt.iterMap(rt.iterZip(rt.iterFrom(rt.place(() => t, (value9) => t = value9), Ticks.next$iter_Iterator), rt.iterFrom({ v: phase }, Phase.next$iter_Iterator, undefined, { hint: (it: rt.Place) => Phase.sizeHint$iter_Iterator(it.v), count: (it: rt.Place) => Phase.count$iter_Iterator(it.v), back: (it: rt.Place) => rt.iterFromOption(Phase.nextBack$iter_DoubleEndedIterator(it)) })), (_27: [rt.u8, rt.u8]): rt.u8 => { + return rt.u8Mul(_27[0], _27[1]); + }), "next"); + rt.iterExtendBytes(out, rt.iterFrom({ v: t }, Ticks.next$iter_Iterator, (it: rt.Place) => drop$iters_Ticks(it.v)), "next"); + } + } + } + const _258: rt.RefCell = rt.refCellBorrow(log); + rt.byteVecExtendFromSlice(out, rt.byteVecSlice(_258.value)); + rt.refRelease(_258); +} + //# sourceMappingURL=iters.ts.map diff --git a/ts/fixtures/lang/iters/expected/lib.ts b/ts/fixtures/lang/iters/expected/lib.ts index 414ea619a..b888595e6 100644 --- a/ts/fixtures/lang/iters/expected/lib.ts +++ b/ts/fixtures/lang/iters/expected/lib.ts @@ -1,7 +1,14 @@ // Generated by rust2-ts. Do not edit. import * as rt from "./rt.ts"; -import { adaptors, consumers, reducers, peekedOthers, skips, ranked, ranges, options, optionItems, own, values, returned, zips, zipsBack, rangeFroms, rangeMethods, compares, lent } from "./iters.ts"; +import { adaptors, consumers, reducers, peekedOthers, skips, ranked, ranges, options, optionItems, own, values, returned, zips, zipsBack, rangeFroms, rangeMethods, compares, lent, byValue } from "./iters.ts"; +import type * as Ticks from "./iters.Ticks.ts"; + +export function drop$iters_Ticks(_1: Ticks.Ticks): void { + if (_1.tag === "Left") { + _1._1[Symbol.dispose](); + } +} export class of$u8 { v: rt.u8; @@ -34,7 +41,7 @@ export function cases(): [string, (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) optionItems(data8, out8); }] as [string, (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) => undefined], ["iters::lent", (_218: rt.u8, data9: rt.ByteSlice, out9: rt.ByteVec): undefined => { lent(data9, out9); - }] as [string, (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) => undefined]]; + }] as [string, (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) => undefined], ["iters::by_value", byValue as (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) => undefined] as [string, (a0: rt.u8, a1: rt.ByteSlice, a2: rt.ByteVec) => undefined]]; } //# sourceMappingURL=lib.ts.map diff --git a/ts/fixtures/lang/iters/src/iters.rs b/ts/fixtures/lang/iters/src/iters.rs index e944e5302..ced5fc0b9 100644 --- a/ts/fixtures/lang/iters/src/iters.rs +++ b/ts/fixtures/lang/iters/src/iters.rs @@ -1919,3 +1919,230 @@ fn halves>(mut it: I, n: usize) -> Vec { let front: Vec = it.by_ref().take(n).collect(); [front, it.take(1).collect()].concat() } + +/// The crate's own iterators taken by value, whose JS value is copied as an enum's is or +/// shared as a struct's is, through adaptors, consumers, `for`, and `IntoIterator`, with +/// what each drops logged where it drops. +pub fn by_value(kind: u8, data: &[u8], out: &mut Vec) { + let log = std::cell::RefCell::new(Vec::new()); + let at = |i: usize| data.get(i).copied().unwrap_or(0); + let phase = Phase::of(at(0)); + let ticks = || Ticks::Left(at(1) % 6, Noted(&log, 0xd0)); + let logged = || Logged { + left: at(2) % 5, + log: &log, + }; + match kind % 13 { + 0 => out.extend(phase.map(|n| n * 3)), + 1 => { + let v: Vec = phase.filter(|n| n % 2 == 0).collect(); + out.extend(v); + } + 2 => out.extend(phase.zip(ticks()).map(|(a, b)| a ^ b)), + 3 => out.extend(ticks().zip(logged()).map(|(a, b)| a + b)), + 4 => out.extend(phase.chain(ticks()).chain(logged())), + 5 => { + for n in ticks() { + log.borrow_mut().push(n); + } + for n in phase { + out.push(n); + } + } + 6 => { + out.push(phase.count() as u8); + out.push(Phase::of(at(1)).last().unwrap_or(0xee)); + out.push(phase.fold(1, |acc, n| acc ^ n)); + out.push(phase.size_hint().0 as u8); + out.push(phase.rev().next().unwrap_or(0xee)); + } + 7 => { + out.push(ticks().count() as u8); + out.push(ticks().last().unwrap_or(0xee)); + out.push(ticks().sum()); + out.push(ticks().nth(1).unwrap_or(0xee)); + out.push(logged().take(2).count() as u8); + } + 8 => { + let mut v = vec![at(3)]; + v.extend(ticks()); + v.extend(phase); + out.extend(v); + } + 9 => { + let bag = Bag(at(0), at(1)); + for n in bag { + out.push(n); + } + out.extend(bag.into_iter().map(|n| n + 1).enumerate().map(|(i, n)| i as u8 ^ n)); + } + 10 => { + // Stopped partway, so what each still holds drops with the adaptor. + let mut it = ticks().map(|n| n * 2).peekable(); + out.extend(it.next()); + out.extend(it.peek().copied()); + drop(it); + let mut it = logged().chain(ticks()).skip(1); + out.extend(it.next()); + log.borrow_mut().push(0xaa); + } + 11 => { + let pairs: Vec<(u8, u8)> = phase.zip(phase.rev()).collect(); + for (a, b) in pairs { + out.push(a * 16 + b); + } + out.push(phase.max().unwrap_or(0xee)); + out.push(u8::from(phase.eq(Phase::of(at(1))))); + // Each pass of a cycle reads a clone of the iterator as it was. + out.extend(phase.into_iter().cycle().take(usize::from(at(1) % 8))); + } + _ => { + // Std's methods taking `&mut self`, and adaptors of a `&mut`, advance the local. + let mut p = phase; + out.extend(p.nth(0)); + out.push(u8::from(p.any(|n| n == 1))); + out.extend(p.by_ref().map(|n| n + 0x10).take(1)); + out.push((&mut p).size_hint().0 as u8); + for n in &mut p { + out.push(n); + break; + } + let lent = &mut p; + out.extend(lent.nth(0)); + out.push(lent.size_hint().0 as u8); + out.extend(p); + let mut t = ticks(); + out.extend(t.find(|n| n % 2 == 0)); + out.extend(t.position(|n| n == 0).map(|i| i as u8)); + out.extend((&mut t).zip(phase).map(|(a, b)| a * b)); + out.extend(t); + } + } + out.extend_from_slice(&log.borrow()); +} + +/// A countdown whose JS value is a string: each step a variant. +#[derive(Clone, Copy)] +enum Phase { + Three, + Two, + One, + Done, +} + +impl Phase { + fn of(b: u8) -> Self { + [Self::Three, Self::Two, Self::One, Self::Done][usize::from(b % 4)] + } + + fn left(self) -> u8 { + match self { + Self::Three => 3, + Self::Two => 2, + Self::One => 1, + Self::Done => 0, + } + } +} + +impl Iterator for Phase { + type Item = u8; + + fn next(&mut self) -> Option { + let left = self.left(); + *self = match self { + Self::Three => Self::Two, + Self::Two => Self::One, + Self::One | Self::Done => Self::Done, + }; + (left != 0).then_some(left) + } + + fn size_hint(&self) -> (usize, Option) { + let left = usize::from(self.left()); + (left, Some(left)) + } + + fn count(self) -> usize { + usize::from(self.left()) + 10 + } +} + +impl DoubleEndedIterator for Phase { + /// From the back, it counts up, ending where the front would. + fn next_back(&mut self) -> Option { + let left = self.left(); + *self = Self::of(4 - left.min(3) + 1); + (left != 0).then_some(4 - left) + } +} + +/// What logs a byte as it drops. +struct Noted<'a>(&'a std::cell::RefCell>, u8); + +impl Drop for Noted<'_> { + fn drop(&mut self) { + self.0.borrow_mut().push(self.1); + } +} + +/// An enum with a field, whose JS value is an object a `&mut` replaces, and which drops +/// what it holds. +enum Ticks<'a> { + Left(u8, Noted<'a>), + Done, +} + +impl Iterator for Ticks<'_> { + type Item = u8; + + fn next(&mut self) -> Option { + match self { + Self::Left(0, noted) => { + noted.1 += 1; + *self = Self::Done; + None + } + Self::Left(left, noted) => { + *left -= 1; + noted.1 += 1; + Some(*left) + } + Self::Done => None, + } + } +} + +/// A struct that logs what it has left as it drops. +struct Logged<'a> { + left: u8, + log: &'a std::cell::RefCell>, +} + +impl Iterator for Logged<'_> { + type Item = u8; + + fn next(&mut self) -> Option { + self.left = self.left.checked_sub(1)?; + Some(self.left + 0x40) + } +} + +impl Drop for Logged<'_> { + fn drop(&mut self) { + self.log.borrow_mut().push(0x80 | self.left); + } +} + +/// A pair that iterates as a `Phase` from each. +#[derive(Clone, Copy)] +struct Bag(u8, u8); + +impl IntoIterator for Bag { + type Item = u8; + type IntoIter = std::iter::Chain; + + fn into_iter(self) -> Self::IntoIter { + Phase::of(self.0).chain(Phase::of(self.1)) + } +} diff --git a/ts/fixtures/lang/iters/src/lib.rs b/ts/fixtures/lang/iters/src/lib.rs index 3093791e8..c93019b34 100644 --- a/ts/fixtures/lang/iters/src/lib.rs +++ b/ts/fixtures/lang/iters/src/lib.rs @@ -36,5 +36,6 @@ fn cases() -> Vec<(&'static str, Case)> { ("iters::compares", iters::compares), ("iters::option_items", |_, data, out| iters::option_items(data, out)), ("iters::lent", |_, data, out| iters::lent(data, out)), + ("iters::by_value", iters::by_value), ] } diff --git a/ts/fixtures/stock/expected/maps.ts b/ts/fixtures/stock/expected/maps.ts index c5ccf6f21..7eb5230fc 100644 --- a/ts/fixtures/stock/expected/maps.ts +++ b/ts/fixtures/stock/expected/maps.ts @@ -732,9 +732,9 @@ export function ends$hashlink_linked_hash_map_Drain_u16_u32_maps_linked_iters_cl } else if (_20 === 1) { item = linked_hash_map_Drain.nextBack$iter_DoubleEndedIterator_u16_u32(it); } else if (_20 === 2) { - item = rt.iterNth(rt.iterFrom(it, linked_hash_map_Drain.next$iter_Iterator_u16_u32, lib_drop$hashlink_linked_hash_map_Drain_u16_u32, { hint: linked_hash_map_Drain.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_Drain.Drain) => rt.iterFromOption(linked_hash_map_Drain.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); + item = rt.iterNth(rt.iterFrom(it, linked_hash_map_Drain.next$iter_Iterator_u16_u32, undefined, { hint: linked_hash_map_Drain.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_Drain.Drain) => rt.iterFromOption(linked_hash_map_Drain.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); } else { - item = rt.iterNthBack(rt.iterFrom(it, linked_hash_map_Drain.next$iter_Iterator_u16_u32, lib_drop$hashlink_linked_hash_map_Drain_u16_u32, { hint: linked_hash_map_Drain.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_Drain.Drain) => rt.iterFromOption(linked_hash_map_Drain.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); + item = rt.iterNthBack(rt.iterFrom(it, linked_hash_map_Drain.next$iter_Iterator_u16_u32, undefined, { hint: linked_hash_map_Drain.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_Drain.Drain) => rt.iterFromOption(linked_hash_map_Drain.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); } put(out, option_mapOr$0iaogpf(item, 256, f)); const _32: [rt.usize, rt.usize | undefined] = linked_hash_map_Drain.sizeHint$iter_Iterator_u16_u32(it); @@ -775,9 +775,9 @@ export function ends$hashlink_linked_hash_map_IntoIter_u16_u32_maps_linked_iters } else if (_20 === 1) { item = linked_hash_map_IntoIter.nextBack$iter_DoubleEndedIterator_u16_u32(it); } else if (_20 === 2) { - item = rt.iterNth(rt.iterFrom(it, linked_hash_map_IntoIter.next$iter_Iterator_u16_u32, lib_drop$hashlink_linked_hash_map_IntoIter_u16_u32, { hint: linked_hash_map_IntoIter.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_IntoIter.IntoIter) => rt.iterFromOption(linked_hash_map_IntoIter.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); + item = rt.iterNth(rt.iterFrom(it, linked_hash_map_IntoIter.next$iter_Iterator_u16_u32, undefined, { hint: linked_hash_map_IntoIter.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_IntoIter.IntoIter) => rt.iterFromOption(linked_hash_map_IntoIter.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); } else { - item = rt.iterNthBack(rt.iterFrom(it, linked_hash_map_IntoIter.next$iter_Iterator_u16_u32, lib_drop$hashlink_linked_hash_map_IntoIter_u16_u32, { hint: linked_hash_map_IntoIter.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_IntoIter.IntoIter) => rt.iterFromOption(linked_hash_map_IntoIter.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); + item = rt.iterNthBack(rt.iterFrom(it, linked_hash_map_IntoIter.next$iter_Iterator_u16_u32, undefined, { hint: linked_hash_map_IntoIter.sizeHint$iter_Iterator_u16_u32, back: (it: linked_hash_map_IntoIter.IntoIter) => rt.iterFromOption(linked_hash_map_IntoIter.nextBack$iter_DoubleEndedIterator_u16_u32(it)) }), n); } put(out, option_mapOr$0iaogpf(item, 256, f)); const _32: [rt.usize, rt.usize | undefined] = linked_hash_map_IntoIter.sizeHint$iter_Iterator_u16_u32(it); diff --git a/ts/src/lower/iter.rs b/ts/src/lower/iter.rs index d45a5d510..aca20c537 100644 --- a/ts/src/lower/iter.rs +++ b/ts/src/lower/iter.rs @@ -536,6 +536,7 @@ fn folds_own<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { fn own_methods<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, owned: bool, span: Span) -> Expr { let item = b.t.iter_item(ty.peel_refs()); let none = item.and_then(|item| b.t.none_arg(item)); + let held = held(b, ty); let mut props = Vec::new(); for (tr, name) in &OWN[1..] { if !owned && !BORROWED.contains(&(tr, name)) { @@ -557,28 +558,28 @@ fn own_methods<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, owned: bool, span ); continue; } - let sym = Expr::Sym(b.t.instance(instance)); + let mut sym = Expr::Sym(b.t.instance(instance)); + let args: &[&str] = match *name { + "size_hint" | "len" | "count" | "last" | "next_back" => &[], + "nth" | "nth_back" => &["n"], + "fold" | "rfold" => &["acc", "f"], + _ => &["f"], + }; + // One held by its place, which a method not taking `&mut self` reads the value of. + let receiver = b.t.sig(instance.def_id(), instance.args).inputs()[0]; + if held && receiver.ref_mutability() != Some(ty::Mutability::Mut) { + sym = through_place(b, ty, sym, args, span); + } // Each that returns an `Option` of an item, as the protocol returns it: an item or // `rt.DONE`. let method = match *name { "next_back" | "nth" | "nth_back" | "last" | "find" | "rfind" | "reduce" => { - let arg = match *name { - "nth" | "nth_back" => Some("n"), - "find" | "rfind" | "reduce" => Some("f"), - _ => None, - }; - let args = [Expr::ident("it")].into_iter().chain(arg.map(Expr::ident)).collect(); - let option = [sym.call(args)].into_iter().chain(none.clone()).collect(); - let it = Param { - name: "it".into(), - ty: Some(b.t.ty(ty.peel_refs(), span)), - }; - // `n` and `f` are typed by their place in `rt.Own`. - let params = [it].into_iter().chain(arg.map(|arg| Param { - name: arg.into(), - ty: None, - })); - Expr::Lambda(params.collect(), Box::new(Expr::rt("iterFromOption", option))) + let call = [Expr::ident("it")] + .into_iter() + .chain(args.iter().map(|&arg| Expr::ident(arg))); + let option = [sym.call(call.collect())].into_iter().chain(none.clone()).collect(); + let params = source_params(b, ty, args, span); + Expr::Lambda(params, Box::new(Expr::rt("iterFromOption", option))) } _ => sym, }; @@ -595,6 +596,47 @@ fn own_methods<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, owned: bool, span } } +/// Whether `rt.iterFrom` holds the crate's own iterator of type `ty`, through references, as +/// an `rt.Place`, as its `next` reads one whose JS value is copied, such as an enum's. +fn held<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { + b.t.needs_place(ty.peel_refs()) +} + +/// Whether `ty` is an iterator of the crate's own whose `&mut` is an `rt.Place`, which std's +/// methods taking `&mut self` read through, as its `next` does. +pub fn held_own<'tcx>(t: &Translator<'_, 'tcx>, ty: Ty<'tcx>) -> bool { + matches!(ty.kind(), ty::Adt(adt, _) if t.own(adt.did())) && t.iter_item(ty).is_some() && t.needs_place(ty) +} + +/// The parameters of a function of the source of `rt.iterFrom` holding the crate's own +/// iterator of type `ty`, then `args`, which are typed by their place in `rt.Own`. +fn source_params<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, args: &[&str], span: Span) -> Vec { + let it = b.t.ty(ty.peel_refs(), span); + let it = match held(b, ty) { + true => Type::Rt("Place", vec![it]), + false => it, + }; + let it = Param { + name: "it".into(), + ty: Some(it), + }; + let args = args.iter().map(|arg| Param { + name: (*arg).into(), + ty: None, + }); + [it].into_iter().chain(args).collect() +} + +/// `f` of the value in the place `rt.iterFrom` holds the crate's own iterator of type `ty` +/// by, then `args`. +fn through_place<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, f: Expr, args: &[&str], span: Span) -> Expr { + let call = [Expr::ident("it").member("v")] + .into_iter() + .chain(args.iter().map(|&arg| Expr::ident(arg))); + let params = source_params(b, ty, args, span); + Expr::Lambda(params, Box::new(f.call(call.collect()))) +} + /// `iter.next_back()` of the crate's own iterator of type `ty`, as the protocol returns it: /// an item or `rt.DONE`. fn own_back<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, iter: Expr) -> Option { @@ -725,10 +767,20 @@ fn peeled_into_iter<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, value: Expr, return Some(match own_next(b, ty) { Some(instance) => { let next = Expr::Sym(b.t.instance(instance)); + // One owned whose `next` reads its place is moved into a place of its own. + let placed = owned && held(b, ty); let drop = match owned && b.t.drops(ty) { + true if placed => { + let drop = b.t.dropper(ty, span); + through_place(b, ty, drop, &[], span) + } true => b.t.dropper(ty, span), false => Expr::undefined(), }; + let value = match placed { + true => Expr::Object(vec![(Key::Name("v".into()), value)]), + false => value, + }; let own = own_methods(b, ty, owned, span); Expr::rt("iterFrom", tail(vec![value, next], vec![drop, own])) } @@ -1055,6 +1107,15 @@ pub fn call<'tcx>( } let self_ty = match (owner, name) { + // The crate's own iterator, which a method taking `&mut self` borrows. + ("Iterator" | "DoubleEndedIterator" | "ExactSizeIterator", _) + if !targ(0)?.is_ref() + && own_next(b, targ(0)?).is_some() + && let receiver = b.t.sig(call.def_id, gargs).inputs()[0] + && receiver.ref_mutability() == Some(ty::Mutability::Mut) => + { + receiver + } ("Iterator" | "DoubleEndedIterator" | "ExactSizeIterator", _) => targ(0)?, ("Peekable", "peek" | "peek_mut" | "next_if" | "next_if_eq") if library::inherent_std(tcx, call.def_id) == Some(Std::Peekable) => @@ -1628,7 +1689,20 @@ fn clones<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, span: Span) -> Option< let tcx = b.t.tcx; let value = |b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>| super::collections::clone_fn(b, ty, span); if own_next(b, ty).is_some() { - return Some(parts(vec![("v", value(b, ty))])); + // A place of its own for the clone of one held by its place. + let clone = match (held(b, ty), value(b, ty)) { + (true, clone) => { + let v = Expr::ident("it").member("v"); + let v = match undefined(&clone) { + true => v, + false => clone.call(vec![v]), + }; + let params = source_params(b, ty, &[], span); + Expr::Lambda(params, Box::new(Expr::Object(vec![(Key::Name("v".into()), v)]))) + } + (false, clone) => clone, + }; + return Some(parts(vec![("v", clone)])); } let ty::Adt(adt, args) = ty.kind() else { return None; diff --git a/ts/src/lower/pointer.rs b/ts/src/lower/pointer.rs index a64604d4f..941175e97 100644 --- a/ts/src/lower/pointer.rs +++ b/ts/src/lower/pointer.rs @@ -419,7 +419,8 @@ pub fn keeps<'tcx>(tcx: ty::TyCtxt<'tcx>, def_id: rustc_hir::def_id::DefId, args /// rather than what it points at: a `MaybeUninit`'s or a `ManuallyDrop`'s, which it points /// into, an `Arc`'s that `make_mut` replaces, a `String`'s that a drain edits as it drops, /// a `Result`'s whose payload JS copies, which `iter_mut` lends as a place that writes the -/// whole `Result`, an iterator's that `by_ref` returns, and a well-known crate's, such as a +/// whole `Result`, an iterator's that `by_ref` returns, the crate's own iterator's that its +/// `next` reads through, and a well-known crate's, such as a /// `Bytes` that `Buf::advance` moves past its front. fn takes_place<'tcx>( t: &Translator<'_, 'tcx>, @@ -432,6 +433,7 @@ fn takes_place<'tcx>( || matches!(owner.as_str(), "Arc" | "Rc") && name == "make_mut" || (owner.as_str(), name.as_str()) == ("String", "drain") || (owner.as_str(), name.as_str()) == ("Iterator", "by_ref") + || matches!(owner.as_str(), "Iterator" | "DoubleEndedIterator") && super::iter::held_own(t, args.type_at(0)) || (owner.as_str(), name.as_str()) == ("Result", "iter_mut") && t.needs_place(args.type_at(0)) // The `&mut` to the crate's own hasher, which its methods take as it is. || (owner.as_str(), name.as_str()) == ("Hash", "hash") && super::collections::own_hasher(t, args.type_at(1))