From cac5e53bd23e95b00a757c7e3be74badd423b9dc Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Wed, 4 Nov 2026 08:42:07 -0800 Subject: [PATCH 1/5] chore(quest): claim quest/m2/ts-model/reference-impls.md Quest-Claim: 17ebe7c00ab0e997 From f1654f587145d781b0f8e55bffd70b35fb1f797a Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Wed, 4 Nov 2026 09:10:30 -0800 Subject: [PATCH 2/5] feat(ts): translate std's AsRef and AsMut through references std's blanket impls on `&T` and `&mut T` forward `as_ref` and `as_mut` to the referent's, as a generic `B: AsRef<[u8]>` at `&[u8]` reaches in moq-net's model. Through `&mut`, `Borrow` and `BorrowMut` lend a place JS copies, and `Ord::max`, `min`, and `clamp` compare by what the places hold. A forwarded `&mut` operand is no longer dereferenced twice. Co-Authored-By: Claude Opus 5.5 --- quest/m2/ts-model/README.md | 3 +- quest/m2/ts-model/reference-impls.md | 13 - .../expected/conversions.Logged.ts | 4 + .../conversions/expected/conversions.Named.ts | 7 + .../lang/conversions/expected/conversions.ts | 2246 ++++++++++++++++- .../lang/conversions/expected/core/option.ts | 7 + .../lang/conversions/src/conversions.rs | 152 +- ts/src/lower/body.rs | 20 +- ts/src/lower/collections.rs | 28 +- ts/src/lower/lend.rs | 2 + ts/src/lower/library.rs | 15 +- ts/src/lower/mir/call.rs | 7 +- 12 files changed, 2459 insertions(+), 45 deletions(-) delete mode 100644 quest/m2/ts-model/reference-impls.md diff --git a/quest/m2/ts-model/README.md b/quest/m2/ts-model/README.md index f8c75378a..9ba4945a7 100644 --- a/quest/m2/ts-model/README.md +++ b/quest/m2/ts-model/README.md @@ -45,7 +45,7 @@ Decided with the maintainer on 2026-10-27, from a census of the model's 22 publi - The end-to-end work stays here: the model's roots, its differential harness, and the `frames.ts` workload. moq writes the binding files `model.toml` names, in its own tree. -The census at the pin on 2026-11-04: 78 refusals. `Timestamp` alone refuses nothing, and +The census at the pin on 2026-11-04: 75 refusals. `Timestamp` alone refuses nothing, and the [model fixture](/ts/README.md#tests)'s harness runs it against native moq-net at the pin; each case it adds as a type translates. Every other root reaches the rest of the model, so each child below unblocks all of them together. The rest is moq's, for its @@ -59,7 +59,6 @@ there, as does the `unsafe` slice of `model/frame.rs`'s `Filled`. - [Writes through a crate's DerefMut](/quest/m2/ts-model/guard-writes.md) - `*guard = value` through kio's lock guards - [Iterators into a crate's own collections](/quest/m2/ts-model/from-iterator.md) - `collect`, `flat_map`, and `flatten` through moq-pattern's `Patterns` -- [std's impls through a reference](/quest/m2/ts-model/reference-impls.md) - `<&[u8] as AsRef<[u8]>>::as_ref` - [Bytes from an owner that drops](/quest/m2/ts-model/bytes-owner.md) - `Bytes::from_owner` of a frame's segment - [rangemap](/quest/m2/ts-model/rangemap.md) - B-tree ranges by a borrowed key, and std's iterators in a crate's fields - [Addresses as identity](/quest/m2/ts-model/addresses.md) - `Arc::as_ptr(a) as usize` as a key, which needs a decision diff --git a/quest/m2/ts-model/reference-impls.md b/quest/m2/ts-model/reference-impls.md deleted file mode 100644 index 722f2cf7c..000000000 --- a/quest/m2/ts-model/reference-impls.md +++ /dev/null @@ -1,13 +0,0 @@ -# [XS] std's impls through a reference - -## Goal - -[rust2-ts](/ts/README.md) translates calls of std's blanket impls on references that -forward to the referent's, such as `<&[u8] as AsRef<[u8]>>::as_ref`, which a generic -`B: AsRef<[u8]>` instantiated at `&[u8]` reaches, proven by differential tests against -native Rust. - -## Plan - -moq-net's `model/frame.rs` reaches `AsRef` this way three times at the pin. Check -`Borrow`, `Deref`, and the comparison traits through `&` for the same gap while there. diff --git a/ts/fixtures/lang/conversions/expected/conversions.Logged.ts b/ts/fixtures/lang/conversions/expected/conversions.Logged.ts index 5bc8bbce0..ad7a3d8e1 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.Logged.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.Logged.ts @@ -43,6 +43,10 @@ export function partialCmp$cmp_PartialOrd(self: Logged, other: Logged): rs.Order return cmp$cmp_Ord(self, other); } +export function eq$cmp_PartialEq(self: Logged, other: Logged): boolean { + return self.id === other.id; +} + /** The value `data` makes from `at`. */ export function make$conversions_Value(data: rs.ByteSlice, at: rs.usize): Logged { return new Logged(byte(data, at) & 127, ((a0: rs.Arc>): rs.Arc> => { diff --git a/ts/fixtures/lang/conversions/expected/conversions.Named.ts b/ts/fixtures/lang/conversions/expected/conversions.Named.ts index a4dbbebc1..dbfac878f 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.Named.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.Named.ts @@ -7,6 +7,13 @@ export function clone$Clone(self: Named): Named { return { id: self.id, name: self.name }; } +export function eq$cmp_PartialEq(self: Named, other: Named): boolean { + if (!(self.id === other.id)) { + return false; + } + return self.name === other.name; +} + export function partialCmp$cmp_PartialOrd(self: Named, other: Named): rs.Ordering | undefined { return cmp$cmp_Ord(self, other); } diff --git a/ts/fixtures/lang/conversions/expected/conversions.ts b/ts/fixtures/lang/conversions/expected/conversions.ts index 27f4fe6ac..f76495a3f 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.ts @@ -7,7 +7,7 @@ import * as Kept from "./conversions.Kept.ts"; import * as Logged from "./conversions.Logged.ts"; import * as Named from "./conversions.Named.ts"; import { thenSome$1gvhopg } from "./core/bool.ts"; -import { unwrapOr$1fr498u as option_unwrapOr$1fr498u, clone$0wpatp7 as option_clone$0wpatp7, clone$14nprly as option_clone$14nprly, clone$13oewp0 as option_clone$13oewp0, clone$0xr8mw0 as option_clone$0xr8mw0, clone$17fv6u9 as option_clone$17fv6u9, clone$0fp7wpk as option_clone$0fp7wpk, clone$1lfse5o as option_clone$1lfse5o, clone$08wmfj8 as option_clone$08wmfj8, clone$1aebjgp as option_clone$1aebjgp } from "./core/option.ts"; +import { unwrapOr$1fr498u as option_unwrapOr$1fr498u, mapOr$14runhi as option_mapOr$14runhi, clone$0wpatp7 as option_clone$0wpatp7, clone$14nprly as option_clone$14nprly, clone$13oewp0 as option_clone$13oewp0, clone$0xr8mw0 as option_clone$0xr8mw0, clone$17fv6u9 as option_clone$17fv6u9, clone$0fp7wpk as option_clone$0fp7wpk, clone$1lfse5o as option_clone$1lfse5o, clone$08wmfj8 as option_clone$08wmfj8, clone$1aebjgp as option_clone$1aebjgp } from "./core/option.ts"; /** The byte at `at`, past `data`'s end its index. */ export function byte(data: rs.ByteSlice, at: rs.usize): rs.u8 { @@ -177,37 +177,46 @@ export function LOG$init(_1: undefined): rs.Arc> { /** * Runs each conversion of the type `kind` picks, but a slice of one `u8`, whose `&mut` - * no slice can view, and [`searched`] of those that order. + * no slice can view, and [`searched`] of those that order; and [`referenced`] of one + * type of each form JS keeps a value in. */ export function conversions(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { const _5: rs.u8 = rs.u8Rem(kind, 14); if (_5 === 0) { ordered$u32(data, out); + referenced$u32(data, out); } else if (_5 === 1) { ordered$u64(data, out); + referenced$u64(data, out); } else if (_5 === 2) { ordered$String(data, out); + referenced$String(data, out); } else if (_5 === 3) { ordered$Option_u16(data, out); + referenced$Option_u16(data, out); } else if (_5 === 4) { ordered$array0_u8(data, out); } else if (_5 === 5) { ordered$array1_u8(data, out); } else if (_5 === 6) { ordered$array3_u8(data, out); + referenced$array3_u8(data, out); } else if (_5 === 7) { ordered$array40_u8(data, out); } else if (_5 === 8) { ordered$array2_u32(data, out); } else if (_5 === 9) { ordered$conversions_Named(data, out); + referenced$conversions_Named(data, out); } else if (_5 === 10) { ordered$Vec_u32(data, out); } else if (_5 === 11) { ordered$Vec_u8(data, out); + referenced$Vec_u8(data, out); } else if (_5 === 12) { converted$u8(data, out); searched$u8(data, out); + referenced$u8(data, out); } else { ((log: rs.Arc>): undefined => { const _52: rs.RefCell = rs.refCellBorrowMut(log.value); @@ -218,8 +227,10 @@ export function conversions(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): v lentOne$conversions_Logged(data, out); lentThrough$conversions_Logged(data, out); searched$conversions_Logged(data, out); + referenced$conversions_Logged(data, out); } measured(data, out); + referencedBytes(data, out); pointed(data, out); boxedKept(data, out); } @@ -5534,4 +5545,2235 @@ export function pointed(data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteVecExtendFromSlice(out, rs.byteSliceFrom(Uint8Array.of(a[1]))); } +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$Option_u16(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: Array = [make$conversions_Value_Option_u16(data, 13), make$conversions_Value_Option_u16(data, 14), make$conversions_Value_Option_u16(data, 15)]; + const list: rs.Vec = rs.vecFrom([make$conversions_Value_Option_u16(data, 16), make$conversions_Value_Option_u16(data, 17)]); + readAs$Option_u16_ref_slice_Option_u16(rs.sliceFrom(array), out); + readAs$Option_u16_ref_ref_slice_Option_u16(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$Option_u16_ref_array3_Option_u16(array, out); + readAs$Option_u16_ref_Vec_Option_u16(list, out); + readAs$Option_u16_mut_Vec_Option_u16(list, out); + readAs$Option_u16_ref_mut_Vec_Option_u16(list, out); + writeAs$Option_u16_mut_slice_Option_u16(rs.sliceFrom(array), make$conversions_Value_Option_u16(data, 18)); + const _35: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 19); + writeAs$Option_u16_mut_array3_Option_u16(array, _35); + const _38: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 20); + writeAs$Option_u16_mut_Vec_Option_u16(list, _38); + let _41: rs.Vec = list; + const _42: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 21); + writeAs$Option_u16_mut_mut_Vec_Option_u16(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$Option_u16_ref_Option_u16(array[0], out); + const at = rs.idx(list.items, 0); + derefPut$Option_u16_mut_Option_u16(rs.place(() => list.items[at], (value2) => list.items[at] = value2), out); + borrowPut$Option_u16_ref_Option_u16(array[1], out); + const at2 = rs.idx(list.items, 1); + borrowPut$Option_u16_mut_Option_u16(rs.place(() => list.items[at2], (value3) => list.items[at2] = value3), out); + const at3 = rs.idx(list.items, 1); + const _60: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 24); + borrowWrite$Option_u16_mut_Option_u16(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); + const _65: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 25); + borrowWrite$Option_u16_mut_Option_u16(rs.place(() => array[1], (value5) => array[1] = value5), _65); + put$conversions_Value_Option_u16(compared$ref_Option_u16(array[0], array[1], out), out); + put$conversions_Value_Option_u16(compared$ref_ref_Option_u16(list.items[rs.idx(list.items, 1)], array[2], out), out); + let _88: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 22); + let _90: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); + put$conversions_Value_Option_u16(compared$mut_Option_u16(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + rs.byteVecPush(out, compared$ref_slice_Option_u16(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: rs.u16 | undefined | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_Option_u16(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$String(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: string[] = [make$conversions_Value_String(data, 13), make$conversions_Value_String(data, 14), make$conversions_Value_String(data, 15)]; + const list: rs.Vec = rs.vecFrom([make$conversions_Value_String(data, 16), make$conversions_Value_String(data, 17)]); + readAs$String_ref_slice_String(rs.sliceFrom(array), out); + readAs$String_ref_ref_slice_String(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$String_ref_array3_String(array, out); + readAs$String_ref_Vec_String(list, out); + readAs$String_mut_Vec_String(list, out); + readAs$String_ref_mut_Vec_String(list, out); + writeAs$String_mut_slice_String(rs.sliceFrom(array), make$conversions_Value_String(data, 18)); + const _35: string = make$conversions_Value_String(data, 19); + writeAs$String_mut_array3_String(array, _35); + const _38: string = make$conversions_Value_String(data, 20); + writeAs$String_mut_Vec_String(list, _38); + let _41: rs.Vec = list; + const _42: string = make$conversions_Value_String(data, 21); + writeAs$String_mut_mut_Vec_String(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$String_ref_String(array[0], out); + const at = rs.idx(list.items, 0); + derefPut$String_mut_String(rs.place(() => list.items[at], (value2) => list.items[at] = value2), out); + borrowPut$String_ref_String(array[1], out); + const at2 = rs.idx(list.items, 1); + borrowPut$String_mut_String(rs.place(() => list.items[at2], (value3) => list.items[at2] = value3), out); + const at3 = rs.idx(list.items, 1); + const _60: string = make$conversions_Value_String(data, 24); + borrowWrite$String_mut_String(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); + const _65: string = make$conversions_Value_String(data, 25); + borrowWrite$String_mut_String(rs.place(() => array[1], (value5) => array[1] = value5), _65); + put$conversions_Value_String(compared$ref_String(array[0], array[1], out), out); + put$conversions_Value_String(compared$ref_ref_String(list.items[rs.idx(list.items, 1)], array[2], out), out); + let _88: string = make$conversions_Value_String(data, 22); + let _90: string = make$conversions_Value_String(data, 23); + put$conversions_Value_String(compared$mut_String(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + rs.byteVecPush(out, compared$ref_slice_String(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: string | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_String(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$Vec_u8(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: rs.ByteVec[] = [make$conversions_Value_Vec_u8(data, 13), make$conversions_Value_Vec_u8(data, 14), make$conversions_Value_Vec_u8(data, 15)]; + const list: rs.Vec = rs.vecFrom([make$conversions_Value_Vec_u8(data, 16), make$conversions_Value_Vec_u8(data, 17)]); + readAs$Vec_u8_ref_slice_Vec_u8(rs.sliceFrom(array), out); + readAs$Vec_u8_ref_ref_slice_Vec_u8(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$Vec_u8_ref_array3_Vec_u8(array, out); + readAs$Vec_u8_ref_Vec_Vec_u8(list, out); + readAs$Vec_u8_mut_Vec_Vec_u8(list, out); + readAs$Vec_u8_ref_mut_Vec_Vec_u8(list, out); + writeAs$Vec_u8_mut_slice_Vec_u8(rs.sliceFrom(array), make$conversions_Value_Vec_u8(data, 18)); + const _35: rs.ByteVec = make$conversions_Value_Vec_u8(data, 19); + writeAs$Vec_u8_mut_array3_Vec_u8(array, _35); + const _38: rs.ByteVec = make$conversions_Value_Vec_u8(data, 20); + writeAs$Vec_u8_mut_Vec_Vec_u8(list, _38); + let _41: rs.Vec = list; + const _42: rs.ByteVec = make$conversions_Value_Vec_u8(data, 21); + writeAs$Vec_u8_mut_mut_Vec_Vec_u8(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$Vec_u8_ref_Vec_u8(array[0], out); + derefPut$Vec_u8_mut_Vec_u8(list.items[rs.idx(list.items, 0)], out); + borrowPut$Vec_u8_ref_Vec_u8(array[1], out); + borrowPut$Vec_u8_mut_Vec_u8(list.items[rs.idx(list.items, 1)], out); + const at3 = rs.idx(list.items, 1); + const _60: rs.ByteVec = make$conversions_Value_Vec_u8(data, 24); + borrowWrite$Vec_u8_mut_Vec_u8(list.items[at3], _60); + const _65: rs.ByteVec = make$conversions_Value_Vec_u8(data, 25); + borrowWrite$Vec_u8_mut_Vec_u8(array[1], _65); + put$conversions_Value_Vec_u8(compared$ref_Vec_u8(array[0], array[1], out), out); + put$conversions_Value_Vec_u8(compared$ref_ref_Vec_u8(list.items[rs.idx(list.items, 1)], array[2], out), out); + const _88: rs.ByteVec = make$conversions_Value_Vec_u8(data, 22); + const _90: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); + put$conversions_Value_Vec_u8(compared$mut_Vec_u8(_88, _90, out), out); + rs.byteVecPush(out, compared$ref_slice_Vec_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: rs.ByteVec | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_Vec_u8(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$array3_u8(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: Uint8Array[] = [copy$array_u8(make$conversions_Value_array3_u8(data, 13)), copy$array_u8(make$conversions_Value_array3_u8(data, 14)), copy$array_u8(make$conversions_Value_array3_u8(data, 15))]; + const list: rs.Vec = rs.vecFrom(copy$array_array3_u8([make$conversions_Value_array3_u8(data, 16), make$conversions_Value_array3_u8(data, 17)]).map(copy$array_u8)); + readAs$array3_u8_ref_slice_array3_u8(rs.sliceFrom(array), out); + readAs$array3_u8_ref_ref_slice_array3_u8(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$array3_u8_ref_array3_array3_u8(array, out); + readAs$array3_u8_ref_Vec_array3_u8(list, out); + readAs$array3_u8_mut_Vec_array3_u8(list, out); + readAs$array3_u8_ref_mut_Vec_array3_u8(list, out); + writeAs$array3_u8_mut_slice_array3_u8(rs.sliceFrom(array), make$conversions_Value_array3_u8(data, 18)); + const _35: Uint8Array = make$conversions_Value_array3_u8(data, 19); + writeAs$array3_u8_mut_array3_array3_u8(array, _35); + const _38: Uint8Array = make$conversions_Value_array3_u8(data, 20); + writeAs$array3_u8_mut_Vec_array3_u8(list, _38); + let _41: rs.Vec = list; + const _42: Uint8Array = make$conversions_Value_array3_u8(data, 21); + writeAs$array3_u8_mut_mut_Vec_array3_u8(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$array3_u8_ref_array3_u8(rs.byteSliceFrom(array[0]), out); + derefPut$array3_u8_mut_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 0)]), out); + borrowPut$array3_u8_ref_array3_u8(rs.byteSliceFrom(array[1]), out); + borrowPut$array3_u8_mut_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), out); + borrowWrite$array3_u8_mut_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), make$conversions_Value_array3_u8(data, 24)); + borrowWrite$array3_u8_mut_array3_u8(rs.byteSliceFrom(array[1]), make$conversions_Value_array3_u8(data, 25)); + put$conversions_Value_array3_u8(compared$ref_array3_u8(rs.byteSliceFrom(array[0]), rs.byteSliceFrom(array[1]), out), out); + put$conversions_Value_array3_u8(compared$ref_ref_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), rs.byteSliceFrom(array[2]), out), out); + put$conversions_Value_array3_u8(compared$mut_array3_u8(rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 22))), rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 23))), out), out); + rs.byteVecPush(out, compared$ref_slice_array3_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterLend(rs.iterSlice(array), rs.byteSliceFrom), rs.iterLend(rs.iterSlice(list.items), rs.byteSliceFrom)); + while (true) { + const _106: rs.ByteSlice | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$conversions_Logged(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: Logged.Logged[] = [Logged.make$conversions_Value(data, 13), Logged.make$conversions_Value(data, 14), Logged.make$conversions_Value(data, 15)]; + const list: rs.Vec = rs.vecFrom([Logged.make$conversions_Value(data, 16), Logged.make$conversions_Value(data, 17)]); + readAs$conversions_Logged_ref_slice_conversions_Logged(rs.sliceFrom(array), out); + readAs$conversions_Logged_ref_ref_slice_conversions_Logged(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$conversions_Logged_ref_array3_conversions_Logged(array, out); + readAs$conversions_Logged_ref_Vec_conversions_Logged(list, out); + readAs$conversions_Logged_mut_Vec_conversions_Logged(list, out); + readAs$conversions_Logged_ref_mut_Vec_conversions_Logged(list, out); + writeAs$conversions_Logged_mut_slice_conversions_Logged(rs.sliceFrom(array), Logged.make$conversions_Value(data, 18)); + const _35: Logged.Logged = Logged.make$conversions_Value(data, 19); + writeAs$conversions_Logged_mut_array3_conversions_Logged(array, _35); + const _38: Logged.Logged = Logged.make$conversions_Value(data, 20); + writeAs$conversions_Logged_mut_Vec_conversions_Logged(list, _38); + let _41: rs.Vec = list; + const _42: Logged.Logged = Logged.make$conversions_Value(data, 21); + writeAs$conversions_Logged_mut_mut_Vec_conversions_Logged(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$conversions_Logged_ref_conversions_Logged(array[0], out); + derefPut$conversions_Logged_mut_conversions_Logged(list.items[rs.idx(list.items, 0)], out); + borrowPut$conversions_Logged_ref_conversions_Logged(array[1], out); + borrowPut$conversions_Logged_mut_conversions_Logged(list.items[rs.idx(list.items, 1)], out); + const at3 = rs.idx(list.items, 1); + const _60: Logged.Logged = Logged.make$conversions_Value(data, 24); + borrowWrite$conversions_Logged_mut_conversions_Logged(list.items[at3], _60); + const _65: Logged.Logged = Logged.make$conversions_Value(data, 25); + borrowWrite$conversions_Logged_mut_conversions_Logged(array[1], _65); + Logged.put$conversions_Value(compared$ref_conversions_Logged(array[0], array[1], out), out); + Logged.put$conversions_Value(compared$ref_ref_conversions_Logged(list.items[rs.idx(list.items, 1)], array[2], out), out); + const _88: Logged.Logged = Logged.make$conversions_Value(data, 22); + const _90: Logged.Logged = Logged.make$conversions_Value(data, 23); + Logged.put$conversions_Value(compared$mut_conversions_Logged(_88, _90, out), out); + _90[Symbol.dispose](); + _88[Symbol.dispose](); + rs.byteVecPush(out, compared$ref_slice_conversions_Logged(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: Logged.Logged | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + Logged.put$conversions_Value(_106, out); + } + rs.dropVec(list); + rs.dropAll(array); +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$conversions_Named(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: Named.Named[] = [Named.make$conversions_Value(data, 13), Named.make$conversions_Value(data, 14), Named.make$conversions_Value(data, 15)]; + const list: rs.Vec = rs.vecFrom([Named.make$conversions_Value(data, 16), Named.make$conversions_Value(data, 17)]); + readAs$conversions_Named_ref_slice_conversions_Named(rs.sliceFrom(array), out); + readAs$conversions_Named_ref_ref_slice_conversions_Named(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$conversions_Named_ref_array3_conversions_Named(array, out); + readAs$conversions_Named_ref_Vec_conversions_Named(list, out); + readAs$conversions_Named_mut_Vec_conversions_Named(list, out); + readAs$conversions_Named_ref_mut_Vec_conversions_Named(list, out); + writeAs$conversions_Named_mut_slice_conversions_Named(rs.sliceFrom(array), Named.make$conversions_Value(data, 18)); + const _35: Named.Named = Named.make$conversions_Value(data, 19); + writeAs$conversions_Named_mut_array3_conversions_Named(array, _35); + const _38: Named.Named = Named.make$conversions_Value(data, 20); + writeAs$conversions_Named_mut_Vec_conversions_Named(list, _38); + let _41: rs.Vec = list; + const _42: Named.Named = Named.make$conversions_Value(data, 21); + writeAs$conversions_Named_mut_mut_Vec_conversions_Named(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$conversions_Named_ref_conversions_Named(array[0], out); + derefPut$conversions_Named_mut_conversions_Named(list.items[rs.idx(list.items, 0)], out); + borrowPut$conversions_Named_ref_conversions_Named(array[1], out); + borrowPut$conversions_Named_mut_conversions_Named(list.items[rs.idx(list.items, 1)], out); + const at3 = rs.idx(list.items, 1); + const _60: Named.Named = Named.make$conversions_Value(data, 24); + borrowWrite$conversions_Named_mut_conversions_Named(list.items[at3], _60); + const _65: Named.Named = Named.make$conversions_Value(data, 25); + borrowWrite$conversions_Named_mut_conversions_Named(array[1], _65); + Named.put$conversions_Value(compared$ref_conversions_Named(array[0], array[1], out), out); + Named.put$conversions_Value(compared$ref_ref_conversions_Named(list.items[rs.idx(list.items, 1)], array[2], out), out); + const _88: Named.Named = Named.make$conversions_Value(data, 22); + const _90: Named.Named = Named.make$conversions_Value(data, 23); + Named.put$conversions_Value(compared$mut_conversions_Named(_88, _90, out), out); + rs.byteVecPush(out, compared$ref_slice_conversions_Named(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: Named.Named | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + Named.put$conversions_Value(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$u32(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: rs.u32[] = [make$conversions_Value_u32(data, 13), make$conversions_Value_u32(data, 14), make$conversions_Value_u32(data, 15)]; + const list: rs.Vec = rs.vecFrom([make$conversions_Value_u32(data, 16), make$conversions_Value_u32(data, 17)]); + readAs$u32_ref_slice_u32(rs.sliceFrom(array), out); + readAs$u32_ref_ref_slice_u32(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$u32_ref_array3_u32(array, out); + readAs$u32_ref_Vec_u32(list, out); + readAs$u32_mut_Vec_u32(list, out); + readAs$u32_ref_mut_Vec_u32(list, out); + writeAs$u32_mut_slice_u32(rs.sliceFrom(array), make$conversions_Value_u32(data, 18)); + const _35: rs.u32 = make$conversions_Value_u32(data, 19); + writeAs$u32_mut_array3_u32(array, _35); + const _38: rs.u32 = make$conversions_Value_u32(data, 20); + writeAs$u32_mut_Vec_u32(list, _38); + let _41: rs.Vec = list; + const _42: rs.u32 = make$conversions_Value_u32(data, 21); + writeAs$u32_mut_mut_Vec_u32(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$u32_ref_u32(array[0], out); + const at = rs.idx(list.items, 0); + derefPut$u32_mut_u32(rs.place(() => list.items[at], (value2) => list.items[at] = value2), out); + borrowPut$u32_ref_u32(array[1], out); + const at2 = rs.idx(list.items, 1); + borrowPut$u32_mut_u32(rs.place(() => list.items[at2], (value3) => list.items[at2] = value3), out); + const at3 = rs.idx(list.items, 1); + const _60: rs.u32 = make$conversions_Value_u32(data, 24); + borrowWrite$u32_mut_u32(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); + const _65: rs.u32 = make$conversions_Value_u32(data, 25); + borrowWrite$u32_mut_u32(rs.place(() => array[1], (value5) => array[1] = value5), _65); + put$conversions_Value_u32(compared$ref_u32(array[0], array[1], out), out); + put$conversions_Value_u32(compared$ref_ref_u32(list.items[rs.idx(list.items, 1)], array[2], out), out); + let _88: rs.u32 = make$conversions_Value_u32(data, 22); + let _90: rs.u32 = make$conversions_Value_u32(data, 23); + put$conversions_Value_u32(compared$mut_u32(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + rs.byteVecPush(out, compared$ref_slice_u32(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: rs.u32 | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_u32(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$u64(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: rs.u64[] = [make$conversions_Value_u64(data, 13), make$conversions_Value_u64(data, 14), make$conversions_Value_u64(data, 15)]; + const list: rs.Vec = rs.vecFrom([make$conversions_Value_u64(data, 16), make$conversions_Value_u64(data, 17)]); + readAs$u64_ref_slice_u64(rs.sliceFrom(array), out); + readAs$u64_ref_ref_slice_u64(rs.sliceRange(rs.sliceFrom(array), 1), out); + readAs$u64_ref_array3_u64(array, out); + readAs$u64_ref_Vec_u64(list, out); + readAs$u64_mut_Vec_u64(list, out); + readAs$u64_ref_mut_Vec_u64(list, out); + writeAs$u64_mut_slice_u64(rs.sliceFrom(array), make$conversions_Value_u64(data, 18)); + const _35: rs.u64 = make$conversions_Value_u64(data, 19); + writeAs$u64_mut_array3_u64(array, _35); + const _38: rs.u64 = make$conversions_Value_u64(data, 20); + writeAs$u64_mut_Vec_u64(list, _38); + let _41: rs.Vec = list; + const _42: rs.u64 = make$conversions_Value_u64(data, 21); + writeAs$u64_mut_mut_Vec_u64(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$u64_ref_u64(array[0], out); + const at = rs.idx(list.items, 0); + derefPut$u64_mut_u64(rs.place(() => list.items[at], (value2) => list.items[at] = value2), out); + borrowPut$u64_ref_u64(array[1], out); + const at2 = rs.idx(list.items, 1); + borrowPut$u64_mut_u64(rs.place(() => list.items[at2], (value3) => list.items[at2] = value3), out); + const at3 = rs.idx(list.items, 1); + const _60: rs.u64 = make$conversions_Value_u64(data, 24); + borrowWrite$u64_mut_u64(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); + const _65: rs.u64 = make$conversions_Value_u64(data, 25); + borrowWrite$u64_mut_u64(rs.place(() => array[1], (value5) => array[1] = value5), _65); + put$conversions_Value_u64(compared$ref_u64(array[0], array[1], out), out); + put$conversions_Value_u64(compared$ref_ref_u64(list.items[rs.idx(list.items, 1)], array[2], out), out); + let _88: rs.u64 = make$conversions_Value_u64(data, 22); + let _90: rs.u64 = make$conversions_Value_u64(data, 23); + put$conversions_Value_u64(compared$mut_u64(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + rs.byteVecPush(out, compared$ref_slice_u64(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); + while (true) { + const _106: rs.u64 | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_u64(_106, out); + } +} + +/** + * std's impls on references, reached by generic functions: `AsRef` and `AsMut` of + * slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which + * forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a + * `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. + */ +export function referenced$u8(data: rs.ByteSlice, out: rs.ByteVec): void { + const array: Uint8Array = Uint8Array.of(make$conversions_Value_u8(data, 13), make$conversions_Value_u8(data, 14), make$conversions_Value_u8(data, 15)); + const list: rs.ByteVec = rs.byteVecFrom(Uint8Array.of(make$conversions_Value_u8(data, 16), make$conversions_Value_u8(data, 17))); + readAs$u8_ref_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 0), out); + readAs$u8_ref_ref_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 1), out); + readAs$u8_ref_array3_u8(rs.byteSliceFrom(array), out); + readAs$u8_ref_Vec_u8(list, out); + readAs$u8_mut_Vec_u8(list, out); + readAs$u8_ref_mut_Vec_u8(list, out); + writeAs$u8_mut_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 0), make$conversions_Value_u8(data, 18)); + writeAs$u8_mut_array3_u8(rs.byteSliceFrom(array), make$conversions_Value_u8(data, 19)); + const _38: rs.u8 = make$conversions_Value_u8(data, 20); + writeAs$u8_mut_Vec_u8(list, _38); + let _41: rs.ByteVec = list; + const _42: rs.u8 = make$conversions_Value_u8(data, 21); + writeAs$u8_mut_mut_Vec_u8(rs.place(() => _41, (value) => _41 = value), _42); + derefPut$u8_ref_u8(array[0], out); + const at = rs.idx(list, 0); + derefPut$u8_mut_u8(rs.place(() => list.data[at], (value2) => list.data[at] = value2), out); + borrowPut$u8_ref_u8(array[1], out); + const at2 = rs.idx(list, 1); + borrowPut$u8_mut_u8(rs.place(() => list.data[at2], (value3) => list.data[at2] = value3), out); + const at3 = rs.idx(list, 1); + const _60: rs.u8 = make$conversions_Value_u8(data, 24); + borrowWrite$u8_mut_u8(rs.place(() => list.data[at3], (value4) => list.data[at3] = value4), _60); + const _65: rs.u8 = make$conversions_Value_u8(data, 25); + borrowWrite$u8_mut_u8(rs.place(() => array[1], (value5) => array[1] = value5), _65); + put$conversions_Value_u8(compared$ref_u8(array[0], array[1], out), out); + put$conversions_Value_u8(compared$ref_ref_u8(list.data[rs.idx(list, 1)], array[2], out), out); + let _88: rs.u8 = make$conversions_Value_u8(data, 22); + let _90: rs.u8 = make$conversions_Value_u8(data, 23); + put$conversions_Value_u8(compared$mut_u8(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + rs.byteVecPush(out, compared$ref_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 0), rs.byteSliceRange(rs.byteVecSlice(list), 0), out).length & 0xff); + const iter: rs.Iter = rs.iterChain(rs.iterSlice(rs.byteSliceView(rs.byteSliceFrom(array))), rs.iterSlice(rs.byteVecView(list))); + while (true) { + const _106: rs.u8 | rs.Done = iter.next(); + if (_106 === rs.DONE) { + break; + } + put$conversions_Value_u8(_106, out); + } +} + +/** + * Bytes through `AsRef<[u8]>` and text through `AsRef` of strings, slices, and + * `Vec`s behind `&`, `&mut`, and a reference to one, as moq's buffers reach them. + */ +export function referencedBytes(data: rs.ByteSlice, out: rs.ByteVec): void { + let text: string = rs.stringExtendChars("", rs.iterMap(rs.iterTake(rs.iterSlice(rs.byteSliceView(data)), 4), (_2: rs.u8): rs.char => { + return _2 as rs.char; + })); + const bytes: rs.ByteVec = rs.byteSliceToByteVec(data); + readBytes$ref_str(text, out); + readBytes$ref_String(text, out); + readBytes$mut_String(rs.place(() => text, (value) => text = value), out); + readBytes$ref_ref_str(text, out); + readBytes$ref_slice_u8(data, out); + readBytes$ref_ref_slice_u8(data, out); + readBytes$ref_Vec_u8(bytes, out); + readBytes$mut_Vec_u8(bytes, out); + readStr$ref_str(text, out); + readStr$ref_String(text, out); + readStr$ref_mut_String(rs.place(() => text, (value2) => text = value2), out); +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_mut_Vec_Option_u16(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_ref_Vec_Option_u16(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_ref_array3_Option_u16(b: Array, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_ref_mut_Vec_Option_u16(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_ref_ref_slice_Option_u16(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Option_u16_ref_slice_Option_u16(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Option_u16(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_mut_Vec_String(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_ref_Vec_String(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_ref_array3_String(b: string[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_ref_mut_Vec_String(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_ref_ref_slice_String(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$String_ref_slice_String(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_String(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_mut_Vec_Vec_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_ref_Vec_Vec_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_ref_array3_Vec_u8(b: rs.ByteVec[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_ref_mut_Vec_Vec_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_ref_ref_slice_Vec_u8(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$Vec_u8_ref_slice_Vec_u8(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_Vec_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_mut_Vec_array3_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_ref_Vec_array3_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_ref_array3_array3_u8(b: Uint8Array[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_ref_mut_Vec_array3_u8(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_ref_ref_slice_array3_u8(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$array3_u8_ref_slice_array3_u8(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + const iter: rs.Iter = rs.iterLend(rs.iterSlice(rs.sliceItems(s)), rs.byteSliceFrom); + while (true) { + const _10: rs.ByteSlice | rs.Done = iter.next(); + if (_10 === rs.DONE) { + break; + } + put$conversions_Value_array3_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_mut_Vec_conversions_Logged(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_ref_Vec_conversions_Logged(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_ref_array3_conversions_Logged(b: Logged.Logged[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_ref_mut_Vec_conversions_Logged(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_ref_ref_slice_conversions_Logged(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Logged_ref_slice_conversions_Logged(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Logged.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_mut_Vec_conversions_Named(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_ref_Vec_conversions_Named(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_ref_array3_conversions_Named(b: Named.Named[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_ref_mut_Vec_conversions_Named(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_ref_ref_slice_conversions_Named(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$conversions_Named_ref_slice_conversions_Named(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + Named.put$conversions_Value(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_mut_Vec_u32(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_ref_Vec_u32(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_ref_array3_u32(b: rs.u32[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_ref_mut_Vec_u32(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_ref_ref_slice_u32(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u32_ref_slice_u32(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u32(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_mut_Vec_u64(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_ref_Vec_u64(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_ref_array3_u64(b: rs.u64[], out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_ref_mut_Vec_u64(b: rs.Vec, out: rs.ByteVec): void { + const s: rs.Slice = rs.sliceFrom(b.items); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_ref_ref_slice_u64(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u64_ref_slice_u64(b: rs.Slice, out: rs.ByteVec): void { + const s: rs.Slice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.sliceItems(s)) { + put$conversions_Value_u64(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_mut_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + const s: rs.ByteSlice = rs.byteVecSlice(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_ref_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + const s: rs.ByteSlice = rs.byteVecSlice(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_ref_array3_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + const s: rs.ByteSlice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_ref_mut_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + const s: rs.ByteSlice = rs.byteVecSlice(b); + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_ref_ref_slice_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + const s: rs.ByteSlice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** What `b` reads as a slice: its length, then each element. */ +export function readAs$u8_ref_slice_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + const s: rs.ByteSlice = b; + rs.byteVecPush(out, s.length & 0xff); + for (const _10 of rs.byteSliceView(s)) { + put$conversions_Value_u8(_10, out); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Option_u16_mut_Vec_Option_u16(b: rs.Vec, value: rs.u16 | undefined): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Option_u16_mut_array3_Option_u16(b: Array, value: rs.u16 | undefined): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Option_u16_mut_mut_Vec_Option_u16(b: rs.Place>, value: rs.u16 | undefined): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Option_u16_mut_slice_Option_u16(b: rs.Slice, value: rs.u16 | undefined): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$String_mut_Vec_String(b: rs.Vec, value: string): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$String_mut_array3_String(b: string[], value: string): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$String_mut_mut_Vec_String(b: rs.Place>, value: string): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$String_mut_slice_String(b: rs.Slice, value: string): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Vec_u8_mut_Vec_Vec_u8(b: rs.Vec, value: rs.ByteVec): void { + const _3: rs.ByteVec | undefined = rs.sliceLast(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Vec_u8_mut_array3_Vec_u8(b: rs.ByteVec[], value: rs.ByteVec): void { + const _3: rs.ByteVec | undefined = rs.sliceLast(rs.sliceFrom(b)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Vec_u8_mut_mut_Vec_Vec_u8(b: rs.Place>, value: rs.ByteVec): void { + const _3: rs.ByteVec | undefined = rs.sliceLast(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$Vec_u8_mut_slice_Vec_u8(b: rs.Slice, value: rs.ByteVec): void { + const _3: rs.ByteVec | undefined = rs.sliceLast(b); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$array3_u8_mut_Vec_array3_u8(b: rs.Vec, value: Uint8Array): void { + value = copy$array_u8(value); + const _3: rs.ByteSlice | undefined = rs.optionMap(rs.sliceLast(rs.sliceFrom(b.items)), rs.byteSliceFrom); + if (_3 !== undefined) { + _3.data.set(value, _3.start); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$array3_u8_mut_array3_array3_u8(b: Uint8Array[], value: Uint8Array): void { + value = copy$array_u8(value); + const _3: rs.ByteSlice | undefined = rs.optionMap(rs.sliceLast(rs.sliceFrom(b)), rs.byteSliceFrom); + if (_3 !== undefined) { + _3.data.set(value, _3.start); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$array3_u8_mut_mut_Vec_array3_u8(b: rs.Place>, value: Uint8Array): void { + value = copy$array_u8(value); + const _3: rs.ByteSlice | undefined = rs.optionMap(rs.sliceLast(rs.sliceFrom(b.v.items)), rs.byteSliceFrom); + if (_3 !== undefined) { + _3.data.set(value, _3.start); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$array3_u8_mut_slice_array3_u8(b: rs.Slice, value: Uint8Array): void { + value = copy$array_u8(value); + const _3: rs.ByteSlice | undefined = rs.optionMap(rs.sliceLast(b), rs.byteSliceFrom); + if (_3 !== undefined) { + _3.data.set(value, _3.start); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Logged_mut_Vec_conversions_Logged(b: rs.Vec, value: Logged.Logged): void { + let _9: boolean = false; + _9 = true; + const _3: Logged.Logged | undefined = rs.sliceLast(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + _9 = false; + _3[Symbol.dispose](); + Object.assign(_3, value); + } + if (_9) { + value[Symbol.dispose](); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Logged_mut_array3_conversions_Logged(b: Logged.Logged[], value: Logged.Logged): void { + let _9: boolean = false; + _9 = true; + const _3: Logged.Logged | undefined = rs.sliceLast(rs.sliceFrom(b)); + if (_3 !== undefined) { + _9 = false; + _3[Symbol.dispose](); + Object.assign(_3, value); + } + if (_9) { + value[Symbol.dispose](); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Logged_mut_mut_Vec_conversions_Logged(b: rs.Place>, value: Logged.Logged): void { + let _9: boolean = false; + _9 = true; + const _3: Logged.Logged | undefined = rs.sliceLast(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + _9 = false; + _3[Symbol.dispose](); + Object.assign(_3, value); + } + if (_9) { + value[Symbol.dispose](); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Logged_mut_slice_conversions_Logged(b: rs.Slice, value: Logged.Logged): void { + let _9: boolean = false; + _9 = true; + const _3: Logged.Logged | undefined = rs.sliceLast(b); + if (_3 !== undefined) { + _9 = false; + _3[Symbol.dispose](); + Object.assign(_3, value); + } + if (_9) { + value[Symbol.dispose](); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Named_mut_Vec_conversions_Named(b: rs.Vec, value: Named.Named): void { + const _3: Named.Named | undefined = rs.sliceLast(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Named_mut_array3_conversions_Named(b: Named.Named[], value: Named.Named): void { + const _3: Named.Named | undefined = rs.sliceLast(rs.sliceFrom(b)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Named_mut_mut_Vec_conversions_Named(b: rs.Place>, value: Named.Named): void { + const _3: Named.Named | undefined = rs.sliceLast(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$conversions_Named_mut_slice_conversions_Named(b: rs.Slice, value: Named.Named): void { + const _3: Named.Named | undefined = rs.sliceLast(b); + if (_3 !== undefined) { + Object.assign(_3, value); + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u32_mut_Vec_u32(b: rs.Vec, value: rs.u32): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u32_mut_array3_u32(b: rs.u32[], value: rs.u32): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u32_mut_mut_Vec_u32(b: rs.Place>, value: rs.u32): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u32_mut_slice_u32(b: rs.Slice, value: rs.u32): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u64_mut_Vec_u64(b: rs.Vec, value: rs.u64): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u64_mut_array3_u64(b: rs.u64[], value: rs.u64): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u64_mut_mut_Vec_u64(b: rs.Place>, value: rs.u64): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.sliceFrom(b.v.items)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u64_mut_slice_u64(b: rs.Slice, value: rs.u64): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u8_mut_Vec_u8(b: rs.ByteVec, value: rs.u8): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.byteVecSlice(b)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u8_mut_array3_u8(b: rs.ByteSlice, value: rs.u8): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u8_mut_mut_Vec_u8(b: rs.Place, value: rs.u8): void { + const _3: rs.Place | undefined = rs.sliceLastMut(rs.byteVecSlice(b.v)); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** Writes `value` over the last element of what `b` lends as a slice. */ +export function writeAs$u8_mut_slice_u8(b: rs.ByteSlice, value: rs.u8): void { + const _3: rs.Place | undefined = rs.sliceLastMut(b); + if (_3 !== undefined) { + _3.v = value; + } +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$Option_u16_mut_Option_u16(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_Option_u16(b.v, out); + put$conversions_Value_Option_u16(b.v, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$Option_u16_ref_Option_u16(b: rs.u16 | undefined, out: rs.ByteVec): void { + put$conversions_Value_Option_u16(b, out); + put$conversions_Value_Option_u16(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$String_mut_String(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_String(b.v, out); + put$conversions_Value_String(b.v, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$String_ref_String(b: string, out: rs.ByteVec): void { + put$conversions_Value_String(b, out); + put$conversions_Value_String(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$Vec_u8_mut_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + put$conversions_Value_Vec_u8(b, out); + put$conversions_Value_Vec_u8(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$Vec_u8_ref_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + put$conversions_Value_Vec_u8(b, out); + put$conversions_Value_Vec_u8(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$array3_u8_mut_array3_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + put$conversions_Value_array3_u8(b, out); + put$conversions_Value_array3_u8(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$array3_u8_ref_array3_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + put$conversions_Value_array3_u8(b, out); + put$conversions_Value_array3_u8(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$conversions_Logged_mut_conversions_Logged(b: Logged.Logged, out: rs.ByteVec): void { + Logged.put$conversions_Value(b, out); + Logged.put$conversions_Value(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$conversions_Logged_ref_conversions_Logged(b: Logged.Logged, out: rs.ByteVec): void { + Logged.put$conversions_Value(b, out); + Logged.put$conversions_Value(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$conversions_Named_mut_conversions_Named(b: Named.Named, out: rs.ByteVec): void { + Named.put$conversions_Value(b, out); + Named.put$conversions_Value(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$conversions_Named_ref_conversions_Named(b: Named.Named, out: rs.ByteVec): void { + Named.put$conversions_Value(b, out); + Named.put$conversions_Value(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u32_mut_u32(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u32(b.v, out); + put$conversions_Value_u32(b.v, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u32_ref_u32(b: rs.u32, out: rs.ByteVec): void { + put$conversions_Value_u32(b, out); + put$conversions_Value_u32(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u64_mut_u64(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u64(b.v, out); + put$conversions_Value_u64(b.v, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u64_ref_u64(b: rs.u64, out: rs.ByteVec): void { + put$conversions_Value_u64(b, out); + put$conversions_Value_u64(b, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u8_mut_u8(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u8(b.v, out); + put$conversions_Value_u8(b.v, out); +} + +/** What `b` derefs to, by `deref` and by `*`. */ +export function derefPut$u8_ref_u8(b: rs.u8, out: rs.ByteVec): void { + put$conversions_Value_u8(b, out); + put$conversions_Value_u8(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$Option_u16_mut_Option_u16(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_Option_u16(b.v, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$Option_u16_ref_Option_u16(b: rs.u16 | undefined, out: rs.ByteVec): void { + put$conversions_Value_Option_u16(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$String_mut_String(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_String(b.v, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$String_ref_String(b: string, out: rs.ByteVec): void { + put$conversions_Value_String(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$Vec_u8_mut_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + put$conversions_Value_Vec_u8(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$Vec_u8_ref_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + put$conversions_Value_Vec_u8(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$array3_u8_mut_array3_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + put$conversions_Value_array3_u8(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$array3_u8_ref_array3_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + put$conversions_Value_array3_u8(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$conversions_Logged_mut_conversions_Logged(b: Logged.Logged, out: rs.ByteVec): void { + Logged.put$conversions_Value(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$conversions_Logged_ref_conversions_Logged(b: Logged.Logged, out: rs.ByteVec): void { + Logged.put$conversions_Value(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$conversions_Named_mut_conversions_Named(b: Named.Named, out: rs.ByteVec): void { + Named.put$conversions_Value(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$conversions_Named_ref_conversions_Named(b: Named.Named, out: rs.ByteVec): void { + Named.put$conversions_Value(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u32_mut_u32(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u32(b.v, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u32_ref_u32(b: rs.u32, out: rs.ByteVec): void { + put$conversions_Value_u32(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u64_mut_u64(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u64(b.v, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u64_ref_u64(b: rs.u64, out: rs.ByteVec): void { + put$conversions_Value_u64(b, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u8_mut_u8(b: rs.Place, out: rs.ByteVec): void { + put$conversions_Value_u8(b.v, out); +} + +/** What `b` lends by `borrow`. */ +export function borrowPut$u8_ref_u8(b: rs.u8, out: rs.ByteVec): void { + put$conversions_Value_u8(b, out); +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$Option_u16_mut_Option_u16(b: rs.Place, value: rs.u16 | undefined): void { + b.v = value; +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$String_mut_String(b: rs.Place, value: string): void { + b.v = value; +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$Vec_u8_mut_Vec_u8(b: rs.ByteVec, value: rs.ByteVec): void { + Object.assign(b, value); +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$array3_u8_mut_array3_u8(b: rs.ByteSlice, value: Uint8Array): void { + const _3: rs.ByteSlice = b; + _3.data.set(copy$array_u8(value), _3.start); +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$conversions_Logged_mut_conversions_Logged(b: Logged.Logged, value: Logged.Logged): void { + const _3: Logged.Logged = b; + _3[Symbol.dispose](); + Object.assign(_3, value); +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$conversions_Named_mut_conversions_Named(b: Named.Named, value: Named.Named): void { + Object.assign(b, value); +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$u32_mut_u32(b: rs.Place, value: rs.u32): void { + b.v = value; +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$u64_mut_u64(b: rs.Place, value: rs.u64): void { + b.v = value; +} + +/** Writes `value` over what `b` lends by `borrow_mut`. */ +export function borrowWrite$u8_mut_u8(b: rs.Place, value: rs.u8): void { + b.v = value; +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_Option_u16(a: rs.Place, b: rs.Place, out: rs.ByteVec): rs.Place { + const _5: boolean = a.v === b.v; + const _8: boolean = a.v !== b.v; + const _11: boolean = rs.cmpOption(rs.cmp)(a.v, b.v) === -1; + const order2 = rs.cmpOption(rs.cmp)(a.v, b.v); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpOption(rs.cmp)(a.v, b.v) === 1; + const order3 = rs.cmpOption(rs.cmp)(a.v, b.v); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpOption(rs.cmp)(a.v, b.v) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpOption(rs.cmp)(a.v, b.v), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cellBy(rs.cmpLt(rs.cmpOption(rs.cmp)))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_String(a: rs.Place, b: rs.Place, out: rs.ByteVec): rs.Place { + const _5: boolean = a.v === b.v; + const _8: boolean = a.v !== b.v; + const _11: boolean = rs.cmpStr(a.v, b.v) === -1; + const order2 = rs.cmpStr(a.v, b.v); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpStr(a.v, b.v) === 1; + const order3 = rs.cmpStr(a.v, b.v); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpStr(a.v, b.v) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpStr(a.v, b.v), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cellBy(rs.cmpLt(rs.cmpStr))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_Vec_u8(a: rs.ByteVec, b: rs.ByteVec, out: rs.ByteVec): rs.ByteVec { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_array3_u8(a: rs.ByteSlice, b: rs.ByteSlice, out: rs.ByteVec): rs.ByteSlice { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_conversions_Logged(a: Logged.Logged, b: Logged.Logged, out: rs.ByteVec): Logged.Logged { + const _5: boolean = Logged.eq$cmp_PartialEq(a, b); + const _8: boolean = !Logged.eq$cmp_PartialEq(a, b); + const _11: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Logged.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Logged.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Logged.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Logged.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Logged.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_conversions_Named(a: Named.Named, b: Named.Named, out: rs.ByteVec): Named.Named { + const _5: boolean = Named.eq$cmp_PartialEq(a, b); + const _8: boolean = !Named.eq$cmp_PartialEq(a, b); + const _11: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Named.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Named.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Named.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Named.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Named.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_u32(a: rs.Place, b: rs.Place, out: rs.ByteVec): rs.Place { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a.v === b.v, a.v !== b.v, a.v < b.v, a.v <= b.v, a.v > b.v, a.v >= b.v], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a.v, b.v) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a.v, b.v), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cellBy(rs.lt)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_u64(a: rs.Place, b: rs.Place, out: rs.ByteVec): rs.Place { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([rs.u64Eq(a.v, b.v), rs.u64Ne(a.v, b.v), rs.u64Lt(a.v, b.v), rs.u64Le(a.v, b.v), rs.u64Gt(a.v, b.v), rs.u64Ge(a.v, b.v)], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a.v, b.v) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a.v, b.v), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cellBy(rs.lt)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$mut_u8(a: rs.Place, b: rs.Place, out: rs.ByteVec): rs.Place { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a.v === b.v, a.v !== b.v, a.v < b.v, a.v <= b.v, a.v > b.v, a.v >= b.v], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a.v, b.v) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a.v, b.v), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cellBy(rs.lt)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_Option_u16(a: rs.u16 | undefined, b: rs.u16 | undefined, out: rs.ByteVec): rs.u16 | undefined { + const _5: boolean = a === b; + const _8: boolean = a !== b; + const _11: boolean = rs.cmpOption(rs.cmp)(a, b) === -1; + const order2 = rs.cmpOption(rs.cmp)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpOption(rs.cmp)(a, b) === 1; + const order3 = rs.cmpOption(rs.cmp)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpOption(rs.cmp)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpOption(rs.cmp)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpOption(rs.cmp))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_String(a: string, b: string, out: rs.ByteVec): string { + const _5: boolean = a === b; + const _8: boolean = a !== b; + const _11: boolean = rs.cmpStr(a, b) === -1; + const order2 = rs.cmpStr(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpStr(a, b) === 1; + const order3 = rs.cmpStr(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpStr(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpStr(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpStr)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_Vec_u8(a: rs.ByteVec, b: rs.ByteVec, out: rs.ByteVec): rs.ByteVec { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_array3_u8(a: rs.ByteSlice, b: rs.ByteSlice, out: rs.ByteVec): rs.ByteSlice { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_conversions_Logged(a: Logged.Logged, b: Logged.Logged, out: rs.ByteVec): Logged.Logged { + const _5: boolean = Logged.eq$cmp_PartialEq(a, b); + const _8: boolean = !Logged.eq$cmp_PartialEq(a, b); + const _11: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Logged.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Logged.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Logged.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Logged.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Logged.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_conversions_Named(a: Named.Named, b: Named.Named, out: rs.ByteVec): Named.Named { + const _5: boolean = Named.eq$cmp_PartialEq(a, b); + const _8: boolean = !Named.eq$cmp_PartialEq(a, b); + const _11: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Named.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Named.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Named.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Named.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Named.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_Option_u16(a: rs.u16 | undefined, b: rs.u16 | undefined, out: rs.ByteVec): rs.u16 | undefined { + const _5: boolean = a === b; + const _8: boolean = a !== b; + const _11: boolean = rs.cmpOption(rs.cmp)(a, b) === -1; + const order2 = rs.cmpOption(rs.cmp)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpOption(rs.cmp)(a, b) === 1; + const order3 = rs.cmpOption(rs.cmp)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpOption(rs.cmp)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpOption(rs.cmp)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpOption(rs.cmp))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_String(a: string, b: string, out: rs.ByteVec): string { + const _5: boolean = a === b; + const _8: boolean = a !== b; + const _11: boolean = rs.cmpStr(a, b) === -1; + const order2 = rs.cmpStr(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpStr(a, b) === 1; + const order3 = rs.cmpStr(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpStr(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpStr(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpStr)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_Vec_u8(a: rs.ByteVec, b: rs.ByteVec, out: rs.ByteVec): rs.ByteVec { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_array3_u8(a: rs.ByteSlice, b: rs.ByteSlice, out: rs.ByteVec): rs.ByteSlice { + const _5: boolean = rs.eqBytes(a, b); + const _8: boolean = !rs.eqBytes(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_conversions_Logged(a: Logged.Logged, b: Logged.Logged, out: rs.ByteVec): Logged.Logged { + const _5: boolean = Logged.eq$cmp_PartialEq(a, b); + const _8: boolean = !Logged.eq$cmp_PartialEq(a, b); + const _11: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Logged.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Logged.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Logged.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Logged.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Logged.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Logged.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_conversions_Named(a: Named.Named, b: Named.Named, out: rs.ByteVec): Named.Named { + const _5: boolean = Named.eq$cmp_PartialEq(a, b); + const _8: boolean = !Named.eq$cmp_PartialEq(a, b); + const _11: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === -1; + const order2 = Named.partialCmp$cmp_PartialOrd(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = Named.partialCmp$cmp_PartialOrd(a, b) === 1; + const order3 = Named.partialCmp$cmp_PartialOrd(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, Named.cmp$cmp_Ord(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(Named.partialCmp$cmp_PartialOrd(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(Named.partialCmp$cmp_PartialOrd)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_u32(a: rs.u32, b: rs.u32, out: rs.ByteVec): rs.u32 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a === b, a !== b, a < b, a <= b, a > b, a >= b], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.max(a, b); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_u64(a: rs.u64, b: rs.u64, out: rs.ByteVec): rs.u64 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([rs.u64Eq(a, b), rs.u64Ne(a, b), rs.u64Lt(a, b), rs.u64Le(a, b), rs.u64Gt(a, b), rs.u64Ge(a, b)], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.u64Max(a, b); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_ref_u8(a: rs.u8, b: rs.u8, out: rs.ByteVec): rs.u8 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a === b, a !== b, a < b, a <= b, a > b, a >= b], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.max(a, b); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_Option_u16(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.same)(a, b); + const _8: boolean = !rs.eqSlice(rs.same)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmpOption(rs.cmp))(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmpOption(rs.cmp)))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_String(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.same)(a, b); + const _8: boolean = !rs.eqSlice(rs.same)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmpStr)(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmpStr)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmpStr)(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmpStr)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmpStr)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmpStr)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmpStr))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_Vec_u8(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.eqBytes)(a, b); + const _8: boolean = !rs.eqSlice(rs.eqBytes)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmpBytes)(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmpBytes)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmpBytes)(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmpBytes)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmpBytes)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmpBytes)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmpBytes))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_array3_u8(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.eqBytes)(a, b); + const _8: boolean = !rs.eqSlice(rs.eqBytes)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmpBytes)(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmpBytes)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmpBytes)(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmpBytes)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmpBytes)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmpBytes)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmpBytes))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_conversions_Logged(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(Logged.eq$cmp_PartialEq)(a, b); + const _8: boolean = !rs.eqSlice(Logged.eq$cmp_PartialEq)(a, b); + const _11: boolean = rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd)(a, b) === -1; + const order2 = rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd)(a, b) === 1; + const order3 = rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(Logged.cmp$cmp_Ord)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(Logged.partialCmp$cmp_PartialOrd))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_conversions_Named(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(Named.eq$cmp_PartialEq)(a, b); + const _8: boolean = !rs.eqSlice(Named.eq$cmp_PartialEq)(a, b); + const _11: boolean = rs.cmpSlice(Named.partialCmp$cmp_PartialOrd)(a, b) === -1; + const order2 = rs.cmpSlice(Named.partialCmp$cmp_PartialOrd)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(Named.partialCmp$cmp_PartialOrd)(a, b) === 1; + const order3 = rs.cmpSlice(Named.partialCmp$cmp_PartialOrd)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(Named.cmp$cmp_Ord)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(Named.partialCmp$cmp_PartialOrd)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(Named.partialCmp$cmp_PartialOrd))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_u32(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.same)(a, b); + const _8: boolean = !rs.eqSlice(rs.same)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmp)(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmp)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmp)(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmp)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmp)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmp)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmp))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_u64(a: rs.Slice, b: rs.Slice, out: rs.ByteVec): rs.Slice { + const _5: boolean = rs.eqSlice(rs.u64Eq)(a, b); + const _8: boolean = !rs.eqSlice(rs.u64Eq)(a, b); + const _11: boolean = rs.cmpSlice(rs.cmp)(a, b) === -1; + const order2 = rs.cmpSlice(rs.cmp)(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpSlice(rs.cmp)(a, b) === 1; + const order3 = rs.cmpSlice(rs.cmp)(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpSlice(rs.cmp)(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpSlice(rs.cmp)(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpSlice(rs.cmp))); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_slice_u8(a: rs.ByteSlice, b: rs.ByteSlice, out: rs.ByteVec): rs.ByteSlice { + const _5: boolean = rs.byteSliceEq(a, b); + const _8: boolean = !rs.byteSliceEq(a, b); + const _11: boolean = rs.cmpBytes(a, b) === -1; + const order2 = rs.cmpBytes(a, b); + const _14: boolean = order2 !== undefined && order2 <= 0; + const _17: boolean = rs.cmpBytes(a, b) === 1; + const order3 = rs.cmpBytes(a, b); + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_5, _8, _11, _14, _17, order3 !== undefined && order3 >= 0], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmpBytes(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmpBytes(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.ordMax(a, b, rs.cmpLt(rs.cmpBytes)); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_u32(a: rs.u32, b: rs.u32, out: rs.ByteVec): rs.u32 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a === b, a !== b, a < b, a <= b, a > b, a >= b], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.max(a, b); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_u64(a: rs.u64, b: rs.u64, out: rs.ByteVec): rs.u64 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([rs.u64Eq(a, b), rs.u64Ne(a, b), rs.u64Lt(a, b), rs.u64Le(a, b), rs.u64Gt(a, b), rs.u64Ge(a, b)], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.u64Max(a, b); +} + +/** Each comparison of `a` with `b`, and the greater. */ +export function compared$ref_u8(a: rs.u8, b: rs.u8, out: rs.ByteVec): rs.u8 { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([a === b, a !== b, a < b, a <= b, a > b, a >= b], (a0: boolean): rs.u8 => { + return a0 ? 1 : 0; + })), undefined, true); + rs.byteVecPush(out, rs.cmp(a, b) & 0xff); + rs.byteVecPush(out, option_mapOr$14runhi(rs.cmp(a, b), 9, (o: rs.Ordering): rs.u8 => { + return o & 0xff; + })); + return rs.max(a, b); +} + +/** The bytes `b` reads as. */ +export function readBytes$mut_String(b: rs.Place, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringAsBytes(b.v).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(b.v)); +} + +/** The bytes `b` reads as. */ +export function readBytes$mut_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.byteVecSlice(b).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.byteVecSlice(b)); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_String(b: string, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringAsBytes(b).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(b)); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_Vec_u8(b: rs.ByteVec, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.byteVecSlice(b).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.byteVecSlice(b)); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_ref_slice_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + rs.byteVecPush(out, b.length & 0xff); + rs.byteVecExtendFromSlice(out, b); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_ref_str(b: string, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringAsBytes(b).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(b)); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_slice_u8(b: rs.ByteSlice, out: rs.ByteVec): void { + rs.byteVecPush(out, b.length & 0xff); + rs.byteVecExtendFromSlice(out, b); +} + +/** The bytes `b` reads as. */ +export function readBytes$ref_str(b: string, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringAsBytes(b).length & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(b)); +} + +/** The text `s` reads as, as bytes. */ +export function readStr$ref_String(s: string, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringLen(s) & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(s)); +} + +/** The text `s` reads as, as bytes. */ +export function readStr$ref_mut_String(s: rs.Place, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringLen(s.v) & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(s.v)); +} + +/** The text `s` reads as, as bytes. */ +export function readStr$ref_str(s: string, out: rs.ByteVec): void { + rs.byteVecPush(out, rs.stringLen(s) & 0xff); + rs.byteVecExtendFromSlice(out, rs.stringAsBytes(s)); +} + //# sourceMappingURL=conversions.ts.map diff --git a/ts/fixtures/lang/conversions/expected/core/option.ts b/ts/fixtures/lang/conversions/expected/core/option.ts index ef47d15d4..b3ab45d2f 100644 --- a/ts/fixtures/lang/conversions/expected/core/option.ts +++ b/ts/fixtures/lang/conversions/expected/core/option.ts @@ -12,6 +12,13 @@ export function unwrapOr$1fr498u(self: rs.u8 | undefined, default_: rs.u8): rs.u return self; } +export function mapOr$14runhi(self: rs.Ordering | undefined, default_: rs.u8, f: (a0: rs.Ordering) => rs.u8): rs.u8 { + if (self === undefined) { + return default_; + } + return f(self); +} + export function clone$0wpatp7(self: rs.u16 | undefined | rs.None): rs.u16 | undefined | rs.None { if (self === rs.None) { return rs.None; diff --git a/ts/fixtures/lang/conversions/src/conversions.rs b/ts/fixtures/lang/conversions/src/conversions.rs index 05bb7b616..02050cd43 100644 --- a/ts/fixtures/lang/conversions/src/conversions.rs +++ b/ts/fixtures/lang/conversions/src/conversions.rs @@ -3,13 +3,16 @@ //! parameter; `binary_search`, by a closure and by a key, and `partition_point` over runs //! of equal elements; `size_of_val` and `align_of_val`; slices, arrays, and cells of one //! value, written through; arrays as slices by `AsRef`, `AsMut`, `Borrow`, and -//! `BorrowMut`, and `Vec`s by those and as themselves; `clone_from` of boxes; and raw -//! pointers of references. Each is generic over the value, run for numbers JS copies, +//! `BorrowMut`, and `Vec`s by those and as themselves; std's impls on references, which +//! `AsRef`, `AsMut`, and the comparisons forward to what they point at and `Deref` and +//! `Borrow` lend; `clone_from` of boxes; and raw pointers of references. Each is generic +//! over the value, run for numbers JS copies, //! strings, `Option`s, arrays and `Vec`s of bytes and of numbers, a struct, and one that //! logs its clones and drops. use std::borrow::{Borrow, BorrowMut}; use std::cell::{Cell, RefCell}; +use std::ops::Deref; use std::rc::Rc; /// A value made from the case's bytes, put back as bytes. @@ -228,24 +231,47 @@ struct Held { } /// Runs each conversion of the type `kind` picks, but a slice of one `u8`, whose `&mut` -/// no slice can view, and [`searched`] of those that order. +/// no slice can view, and [`searched`] of those that order; and [`referenced`] of one +/// type of each form JS keeps a value in. pub fn conversions(kind: u8, data: &[u8], out: &mut Vec) { match kind % 14 { - 0 => ordered::(data, out), - 1 => ordered::(data, out), - 2 => ordered::(data, out), - 3 => ordered::>(data, out), + 0 => { + ordered::(data, out); + referenced::(data, out); + } + 1 => { + ordered::(data, out); + referenced::(data, out); + } + 2 => { + ordered::(data, out); + referenced::(data, out); + } + 3 => { + ordered::>(data, out); + referenced::>(data, out); + } 4 => ordered::<[u8; 0]>(data, out), 5 => ordered::<[u8; 1]>(data, out), - 6 => ordered::<[u8; 3]>(data, out), + 6 => { + ordered::<[u8; 3]>(data, out); + referenced::<[u8; 3]>(data, out); + } 7 => ordered::<[u8; 40]>(data, out), 8 => ordered::<[u32; 2]>(data, out), - 9 => ordered::(data, out), + 9 => { + ordered::(data, out); + referenced::(data, out); + } 10 => ordered::>(data, out), - 11 => ordered::>(data, out), + 11 => { + ordered::>(data, out); + referenced::>(data, out); + } 12 => { converted::(data, out); searched::(data, out); + referenced::(data, out); } _ => { // What an earlier case dropped at its end, which JS runs on after. @@ -254,9 +280,11 @@ pub fn conversions(kind: u8, data: &[u8], out: &mut Vec) { lent_one::(data, out); lent_through::(data, out); searched::(data, out); + referenced::(data, out); } } measured(data, out); + referenced_bytes(data, out); pointed(data, out); boxed_kept(data, out); } @@ -622,3 +650,107 @@ fn pointed(data: &[u8], out: &mut Vec) { let one = std::array::from_ref(&a[1]); out.extend_from_slice(one); } + +/// std's impls on references, reached by generic functions: `AsRef` and `AsMut` of +/// slices, arrays, and `Vec`s through `&`, `&mut`, and a reference to either, which +/// forward to what each points at; `Deref`, `Borrow`, and `BorrowMut` of a `&` and a +/// `&mut`, which lend what it points at; and the comparisons of references to elements and to slices. +fn referenced(data: &[u8], out: &mut Vec) { + let mut array = [T::make(data, 13), T::make(data, 14), T::make(data, 15)]; + let mut list = vec![T::make(data, 16), T::make(data, 17)]; + read_as(&array[..], out); + read_as(&&array[1..], out); + read_as(&array, out); + read_as(&list, out); + read_as(&mut list, out); + read_as(&&mut list, out); + write_as(&mut array[..], T::make(data, 18)); + write_as(&mut array, T::make(data, 19)); + write_as(&mut list, T::make(data, 20)); + write_as(&mut &mut list, T::make(data, 21)); + deref_put(&array[0], out); + deref_put(&mut list[0], out); + borrow_put::(&array[1], out); + borrow_put::(&mut list[1], out); + borrow_write(&mut list[1], T::make(data, 24)); + borrow_write(&mut array[1], T::make(data, 25)); + compared(&array[0], &array[1], out).put(out); + compared(&&list[1], &&array[2], out).put(out); + compared(&mut T::make(data, 22), &mut T::make(data, 23), out).put(out); + let max = compared(&array[..], &list[..], out); + out.push(max.len() as u8); + for x in array.iter().chain(&list) { + x.put(out); + } +} + +/// Bytes through `AsRef<[u8]>` and text through `AsRef` of strings, slices, and +/// `Vec`s behind `&`, `&mut`, and a reference to one, as moq's buffers reach them. +fn referenced_bytes(data: &[u8], out: &mut Vec) { + let mut text: String = data.iter().take(4).map(|&b| char::from(b)).collect(); + let mut bytes = data.to_vec(); + read_bytes(text.as_str(), out); + read_bytes(&text, out); + read_bytes(&mut text, out); + read_bytes(&&*text, out); + read_bytes(data, out); + read_bytes(&data, out); + read_bytes(&bytes, out); + read_bytes(&mut bytes, out); + read_str(text.as_str(), out); + read_str(&text, out); + read_str(&&mut text, out); +} + +/// What `b` reads as a slice: its length, then each element. +fn read_as>(b: B, out: &mut Vec) { + let s = b.as_ref(); + out.push(s.len() as u8); + for x in s { + x.put(out); + } +} + +/// Writes `value` over the last element of what `b` lends as a slice. +fn write_as>(mut b: B, value: T) { + if let Some(last) = b.as_mut().last_mut() { + *last = value; + } +} + +/// What `b` derefs to, by `deref` and by `*`. +fn deref_put>(b: B, out: &mut Vec) { + b.deref().put(out); + (*b).put(out); +} + +/// What `b` lends by `borrow`. +fn borrow_put>(b: B, out: &mut Vec) { + b.borrow().put(out); +} + +/// Writes `value` over what `b` lends by `borrow_mut`. +fn borrow_write>(mut b: B, value: T) { + *b.borrow_mut() = value; +} + +/// Each comparison of `a` with `b`, and the greater. +fn compared(a: A, b: A, out: &mut Vec) -> A { + let order = [a == b, a != b, a < b, a <= b, a > b, a >= b]; + out.extend(order.map(u8::from)); + out.push(a.cmp(&b) as u8); + out.push(a.partial_cmp(&b).map_or(9, |o| o as u8)); + a.max(b) +} + +/// The bytes `b` reads as. +fn read_bytes>(b: B, out: &mut Vec) { + out.push(b.as_ref().len() as u8); + out.extend_from_slice(b.as_ref()); +} + +/// The text `s` reads as, as bytes. +fn read_str>(s: S, out: &mut Vec) { + out.push(s.as_ref().len() as u8); + out.extend_from_slice(s.as_ref().as_bytes()); +} diff --git a/ts/src/lower/body.rs b/ts/src/lower/body.rs index 59bffa589..9a8c2d556 100644 --- a/ts/src/lower/body.rs +++ b/ts/src/lower/body.rs @@ -198,16 +198,30 @@ impl<'b, 'a, 'tcx> Body<'b, 'a, 'tcx> { if let Some(referent) = library::referent(tcx, def_id, gargs, instance) { // An operand that was a reference to an `rs.Place`, as `&&mut u32` is, passes // what the Place points at, and a `&mut` to a `&mut` or a box what the place it - // is holds, as JS holds a box as what it holds, but where that is a place too. + // is holds, as JS holds a box as what it holds, but where that is a place too. A + // mapping that takes what a `&mut` points at, as `pointees` says, was given the + // inner `&mut`, and takes what that points at. let inputs = |gargs| self.t.sig(def_id, gargs).inputs().to_vec(); + let pointees = |gargs| super::pointer::pointees(self.t, def_id, gargs); + let (given, taken) = (pointees(gargs), pointees(referent)); let args = std::iter::zip(args, std::iter::zip(inputs(gargs), inputs(referent))) - .map(|(arg, (was, now))| match was.kind() { + .enumerate() + .map(|(i, (arg, (was, now)))| match was.kind() { _ if was == now => arg, ty::Ref(_, inner, mutability) if inner.is_box() => match mutability { ty::Mutability::Mut if self.t.place_pointee(now).is_none() => self.t.pointee_value(was, arg), _ => arg, }, - ty::Ref(_, _, ty::Mutability::Mut) => self.t.pointee_value(was, arg), + ty::Ref(_, _, ty::Mutability::Mut) => { + let inner = match given[i] { + true => arg, + false => self.t.pointee_value(was, arg), + }; + match taken[i] { + true => self.t.pointee_value(now, inner), + false => inner, + } + } ty::Ref(_, inner, _) => self.t.pointee_value(*inner, arg), _ => arg, }) diff --git a/ts/src/lower/collections.rs b/ts/src/lower/collections.rs index fee306796..88c35b7f9 100644 --- a/ts/src/lower/collections.rs +++ b/ts/src/lower/collections.rs @@ -71,16 +71,24 @@ pub fn call<'tcx>( return Ok(Some(f.call(args))); } // `Ord`'s defaults, of a std type or the crate's, which compare by `PartialOrd`'s `<`, - // `<=`, and `>`. + // `<=`, and `>`, and of `&mut`s to values JS copies, their `rs.Place`s, by what they + // hold, as std's impls for a `&mut` forward them. ("Ord", "max" | "min" | "clamp", ..) if let Some(t) = self_ty => { - let t = peel_ord(b, t, false); + let held = b.t.place_pointee(t); + let t = peel_ord(b, held.unwrap_or(t), false); let own = matches!(t.kind(), ty::Adt(adt, _) if b.t.own(adt.did())) || pointee(b, t).is_some(); - if !(std_key(b, t) || own) || Int::of(t).is_some() { + if !(std_key(b, t) || own) || held.is_none() && Int::of(t).is_some() { return Err(args); } let tests: &[&str] = if name == "clamp" { &["le", "lt", "gt"] } else { &["lt"] }; let mut values = args; - values.extend(tests.iter().map(|test| test_fn(b, t, test, span))); + for test in tests { + let f = test_fn(b, t, test, span); + values.push(match held { + Some(_) => Expr::rs("cellBy", vec![f]), + None => f, + }); + } // What drops the operands it does not return. let Some(droppers) = b.t.droppers(self_ty, span) else { return Ok(Some(Expr::undefined())); @@ -155,9 +163,15 @@ pub fn call<'tcx>( } ("Borrow", "borrow", ..) | ("BorrowMut", "borrow_mut", ..) if let Some(t) = self_ty => { let by = library::targ(call.args, 1); - let value = match (same_key(b, t, by), arc_of(b, peel(b, t))) { - (true, _) => args.pop(), - (false, Some(inner)) if same_key(b, inner, by) => args.pop().map(|v| v.member("value")), + let value = match (same_key(b, t, by), arc_of(b, peel(b, t)), b.t.place_pointee(t)) { + (true, ..) => args.pop(), + (false, Some(inner), _) if same_key(b, inner, by) => args.pop().map(|v| v.member("value")), + // A `&mut` to a value JS copies, its `rs.Place`: what it holds for `borrow`, and + // itself for `borrow_mut`, whose receiver is given as what it points at. + (false, _, Some(inner)) if same_key(b, inner, by) => args.pop().map(|place| match name { + "borrow" => b.t.pointee_value(t, place), + _ => place, + }), _ => return Err(args), }; return Ok(value); diff --git a/ts/src/lower/lend.rs b/ts/src/lower/lend.rs index 7e42bbf46..d7071de58 100644 --- a/ts/src/lower/lend.rs +++ b/ts/src/lower/lend.rs @@ -77,8 +77,10 @@ pub fn plan<'tcx>(t: &Translator<'_, 'tcx>, def_id: DefId, args: GenericArgsRef< | ("raw" | "array" | "Cell" | "ptr", "from_mut") => true, // `Clone::clone`, which takes the slice, and an array as a slice, which it is. ("ToOwned", "to_owned") => true, + // An array as a slice, which it is, and what a reference lends, which it is too. ("AsRef" | "AsMut" | "Borrow" | "BorrowMut", _) => { args.type_at(0).is_array() && args.type_at(1).is_slice() + || matches!(args.type_at(0).kind(), ty::Ref(_, inner, _) if *inner == args.type_at(1)) } ("IntoIterator", "into_iter") => self_ty.is_some_and(|s| { let s = super::iter::unbox_ref(tcx, s).peel_refs(); diff --git a/ts/src/lower/library.rs b/ts/src/lower/library.rs index 1f2551563..f715a883d 100644 --- a/ts/src/lower/library.rs +++ b/ts/src/lower/library.rs @@ -662,10 +662,10 @@ pub fn is_std(tcx: TyCtxt<'_>, did: DefId) -> bool { matches!(tcx.crate_name(did.krate).as_str(), "core" | "alloc" | "std") } -/// If `instance` is a method of std's `PartialEq`, `PartialOrd`, `Ord`, or `Hash` impl -/// for references, or of its `Hasher` or `fmt::Write` impl for a `&mut`, or its `Hasher` -/// impl for a box, which calls its -/// referents' with the operands dereferenced, the generic arguments of that call. +/// If `instance` is a method of std's `PartialEq`, `PartialOrd`, `Ord`, `Hash`, `AsRef`, or +/// `AsMut` impl for references, or of its `Hasher` or `fmt::Write` impl for a `&mut`, or its +/// `Hasher` impl for a box, which calls its referents' with the operands dereferenced, the +/// generic arguments of that call. pub fn referent<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -681,7 +681,7 @@ pub fn referent<'tcx>( let hasher = std_path(tcx, tr) == ["hash", "Hasher"]; let operands = match tcx.get_diagnostic_name(tr).as_ref().map(|n| n.as_str()) { Some("PartialEq" | "PartialOrd") => 2, - Some("Ord" | "Hash" | "FmtWrite") => 1, + Some("Ord" | "Hash" | "FmtWrite" | "AsRef" | "AsMut") => 1, _ if hasher => 1, _ => return None, }; @@ -2201,6 +2201,8 @@ fn mapping<'tcx>( false => Expr::rs("sliceFrom", vec![Expr::Array(vec![value])]), } } + // A slice or a `str` as itself. + ("AsRef", "as_ref") | ("AsMut", "as_mut") if targ(gargs, 0) == targ(gargs, 1) => args.pop()?, // The slice of all of an array, as `as_slice` has it. ("AsRef", "as_ref") | ("AsMut", "as_mut") | ("Borrow", "borrow") | ("BorrowMut", "borrow_mut") if targ(gargs, 0).is_array() && targ(gargs, 1).is_slice() => @@ -2862,6 +2864,9 @@ fn mapping<'tcx>( // A `Cow`'s text, whichever variant holds it. ("Cow", "into_owned") if targ(gargs, 0).is_str() => Expr::rs("strCowStr", args), ("AsRef", "as_ref") if string(tcx, targ(gargs, 0)) && targ(gargs, 1).is_str() => args.pop()?, + ("AsRef", "as_ref") if string(tcx, targ(gargs, 0)) && byte_slice(targ(gargs, 1)) => { + Expr::rs("stringAsBytes", args) + } // A `Cow<[T]>` borrows its slice, and its `Vec` is its own or a clone of what it // borrows, so it drops nothing. ("Cow", "into_owned") if let ty::Slice(elem) = targ(gargs, 0).kind() => { diff --git a/ts/src/lower/mir/call.rs b/ts/src/lower/mir/call.rs index 417ab7fed..e6e571dde 100644 --- a/ts/src/lower/mir/call.rs +++ b/ts/src/lower/mir/call.rs @@ -404,9 +404,9 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { // Mappings that lend an element JS copies as its place, as a map's `get_mut` does, the // item a `Peekable` peeked, the place a `&mut dyn Any` wraps, a `RefCell` key's value, // a `Result`'s payload, the value of an `Arc`, a lock, or a cell, what a write guard - // lends its map or its leak, the `&mut` an iterator's `by_ref` is given, what `zip` - // makes of the collection it is given by `into_iter`, as the free `zip` does of either, - // or an empty iterator, made or defaulted, which lends nothing. + // lends its map or its leak, what `borrow_mut` lends, the `&mut` an iterator's `by_ref` + // is given, what `zip` makes of the collection it is given by `into_iter`, as the free + // `zip` does of either, or an empty iterator, made or defaulted, which lends nothing. let lends = match library::key(tcx, def_id) { Some((owner, name)) => match (owner.as_str(), name.as_str()) { ("slice", "get_mut" | "first_mut" | "last_mut" | "iter_mut" | "split_first_mut" | "split_last_mut") @@ -419,6 +419,7 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { | ("Mutex" | "RwLock" | "RefCell" | "OnceCell" | "OnceLock", "get_mut") | ("RefMut", "leak") | ("RefCell", "undo_leak" | "replace_with") + | ("BorrowMut", "borrow_mut") | ("Iterator", "by_ref" | "scan") | ("empty", "empty") | ( From d8fc0d60635700341d685b6d6eb1dead3d199c00 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Wed, 4 Nov 2026 09:40:47 -0800 Subject: [PATCH 3/5] fix(ts): lend BorrowMut's receiver as its place `borrow_mut` takes its receiver as the `rs.Place` it may be, so std's impl for any `T` lends the place itself and the one for a `&mut` the place that holds. Co-Authored-By: Claude Opus 5.5 --- .../lang/conversions/expected/conversions.ts | 166 ++++++++++++------ .../lang/conversions/src/conversions.rs | 5 + ts/src/lower/collections.rs | 20 ++- ts/src/lower/pointer.rs | 5 +- 4 files changed, 133 insertions(+), 63 deletions(-) diff --git a/ts/fixtures/lang/conversions/expected/conversions.ts b/ts/fixtures/lang/conversions/expected/conversions.ts index f76495a3f..844a6cda8 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.ts @@ -5579,19 +5579,25 @@ export function referenced$Option_u16(data: rs.ByteSlice, out: rs.ByteVec): void borrowWrite$Option_u16_mut_Option_u16(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); const _65: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 25); borrowWrite$Option_u16_mut_Option_u16(rs.place(() => array[1], (value5) => array[1] = value5), _65); + let whole: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 26); + whole = make$conversions_Value_Option_u16(data, 27); + put$conversions_Value_Option_u16(whole, out); + const _74: rs.Vec = list; + const _77: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 28); + _74.items.push(_77); put$conversions_Value_Option_u16(compared$ref_Option_u16(array[0], array[1], out), out); put$conversions_Value_Option_u16(compared$ref_ref_Option_u16(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _88: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 22); - let _90: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); - put$conversions_Value_Option_u16(compared$mut_Option_u16(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + let _100: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 22); + let _102: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); + put$conversions_Value_Option_u16(compared$mut_Option_u16(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); rs.byteVecPush(out, compared$ref_slice_Option_u16(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: rs.u16 | undefined | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.u16 | undefined | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_Option_u16(_106, out); + put$conversions_Value_Option_u16(_118, out); } } @@ -5629,19 +5635,25 @@ export function referenced$String(data: rs.ByteSlice, out: rs.ByteVec): void { borrowWrite$String_mut_String(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); const _65: string = make$conversions_Value_String(data, 25); borrowWrite$String_mut_String(rs.place(() => array[1], (value5) => array[1] = value5), _65); + let whole: string = make$conversions_Value_String(data, 26); + whole = make$conversions_Value_String(data, 27); + put$conversions_Value_String(whole, out); + const _74: rs.Vec = list; + const _77: string = make$conversions_Value_String(data, 28); + _74.items.push(_77); put$conversions_Value_String(compared$ref_String(array[0], array[1], out), out); put$conversions_Value_String(compared$ref_ref_String(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _88: string = make$conversions_Value_String(data, 22); - let _90: string = make$conversions_Value_String(data, 23); - put$conversions_Value_String(compared$mut_String(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + let _100: string = make$conversions_Value_String(data, 22); + let _102: string = make$conversions_Value_String(data, 23); + put$conversions_Value_String(compared$mut_String(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); rs.byteVecPush(out, compared$ref_slice_String(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: string | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: string | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_String(_106, out); + put$conversions_Value_String(_118, out); } } @@ -5677,19 +5689,26 @@ export function referenced$Vec_u8(data: rs.ByteSlice, out: rs.ByteVec): void { borrowWrite$Vec_u8_mut_Vec_u8(list.items[at3], _60); const _65: rs.ByteVec = make$conversions_Value_Vec_u8(data, 25); borrowWrite$Vec_u8_mut_Vec_u8(array[1], _65); + const whole: rs.ByteVec = make$conversions_Value_Vec_u8(data, 26); + const _67: rs.ByteVec = make$conversions_Value_Vec_u8(data, 27); + Object.assign(whole, _67); + put$conversions_Value_Vec_u8(whole, out); + const _74: rs.Vec = list; + const _77: rs.ByteVec = make$conversions_Value_Vec_u8(data, 28); + _74.items.push(_77); put$conversions_Value_Vec_u8(compared$ref_Vec_u8(array[0], array[1], out), out); put$conversions_Value_Vec_u8(compared$ref_ref_Vec_u8(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _88: rs.ByteVec = make$conversions_Value_Vec_u8(data, 22); - const _90: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); - put$conversions_Value_Vec_u8(compared$mut_Vec_u8(_88, _90, out), out); + const _100: rs.ByteVec = make$conversions_Value_Vec_u8(data, 22); + const _102: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); + put$conversions_Value_Vec_u8(compared$mut_Vec_u8(_100, _102, out), out); rs.byteVecPush(out, compared$ref_slice_Vec_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: rs.ByteVec | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.ByteVec | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_Vec_u8(_106, out); + put$conversions_Value_Vec_u8(_118, out); } } @@ -5722,17 +5741,25 @@ export function referenced$array3_u8(data: rs.ByteSlice, out: rs.ByteVec): void borrowPut$array3_u8_mut_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), out); borrowWrite$array3_u8_mut_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), make$conversions_Value_array3_u8(data, 24)); borrowWrite$array3_u8_mut_array3_u8(rs.byteSliceFrom(array[1]), make$conversions_Value_array3_u8(data, 25)); + const whole: Uint8Array = copy$array_u8(make$conversions_Value_array3_u8(data, 26)); + const _67: Uint8Array = copy$array_u8(make$conversions_Value_array3_u8(data, 27)); + const _68: rs.ByteSlice = rs.byteSliceFrom(rs.byteSliceView(rs.byteSliceFrom(whole))); + _68.data.set(_67, _68.start); + put$conversions_Value_array3_u8(rs.byteSliceFrom(rs.byteSliceView(rs.byteSliceFrom(whole))), out); + const _74: rs.Vec = list; + const _77: Uint8Array = copy$array_u8(make$conversions_Value_array3_u8(data, 28)); + _74.items.push(_77); put$conversions_Value_array3_u8(compared$ref_array3_u8(rs.byteSliceFrom(array[0]), rs.byteSliceFrom(array[1]), out), out); put$conversions_Value_array3_u8(compared$ref_ref_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), rs.byteSliceFrom(array[2]), out), out); put$conversions_Value_array3_u8(compared$mut_array3_u8(rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 22))), rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 23))), out), out); rs.byteVecPush(out, compared$ref_slice_array3_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterLend(rs.iterSlice(array), rs.byteSliceFrom), rs.iterLend(rs.iterSlice(list.items), rs.byteSliceFrom)); while (true) { - const _106: rs.ByteSlice | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.ByteSlice | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_array3_u8(_106, out); + put$conversions_Value_array3_u8(_118, out); } } @@ -5768,22 +5795,32 @@ export function referenced$conversions_Logged(data: rs.ByteSlice, out: rs.ByteVe borrowWrite$conversions_Logged_mut_conversions_Logged(list.items[at3], _60); const _65: Logged.Logged = Logged.make$conversions_Value(data, 25); borrowWrite$conversions_Logged_mut_conversions_Logged(array[1], _65); + const whole: Logged.Logged = Logged.make$conversions_Value(data, 26); + const _67: Logged.Logged = Logged.make$conversions_Value(data, 27); + const _68: Logged.Logged = whole; + _68[Symbol.dispose](); + Object.assign(_68, _67); + Logged.put$conversions_Value(whole, out); + const _74: rs.Vec = list; + const _77: Logged.Logged = Logged.make$conversions_Value(data, 28); + _74.items.push(_77); Logged.put$conversions_Value(compared$ref_conversions_Logged(array[0], array[1], out), out); Logged.put$conversions_Value(compared$ref_ref_conversions_Logged(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _88: Logged.Logged = Logged.make$conversions_Value(data, 22); - const _90: Logged.Logged = Logged.make$conversions_Value(data, 23); - Logged.put$conversions_Value(compared$mut_conversions_Logged(_88, _90, out), out); - _90[Symbol.dispose](); - _88[Symbol.dispose](); + const _100: Logged.Logged = Logged.make$conversions_Value(data, 22); + const _102: Logged.Logged = Logged.make$conversions_Value(data, 23); + Logged.put$conversions_Value(compared$mut_conversions_Logged(_100, _102, out), out); + _102[Symbol.dispose](); + _100[Symbol.dispose](); rs.byteVecPush(out, compared$ref_slice_conversions_Logged(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: Logged.Logged | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: Logged.Logged | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - Logged.put$conversions_Value(_106, out); + Logged.put$conversions_Value(_118, out); } + whole[Symbol.dispose](); rs.dropVec(list); rs.dropAll(array); } @@ -5820,19 +5857,26 @@ export function referenced$conversions_Named(data: rs.ByteSlice, out: rs.ByteVec borrowWrite$conversions_Named_mut_conversions_Named(list.items[at3], _60); const _65: Named.Named = Named.make$conversions_Value(data, 25); borrowWrite$conversions_Named_mut_conversions_Named(array[1], _65); + const whole: Named.Named = Named.make$conversions_Value(data, 26); + const _67: Named.Named = Named.make$conversions_Value(data, 27); + Object.assign(whole, _67); + Named.put$conversions_Value(whole, out); + const _74: rs.Vec = list; + const _77: Named.Named = Named.make$conversions_Value(data, 28); + _74.items.push(_77); Named.put$conversions_Value(compared$ref_conversions_Named(array[0], array[1], out), out); Named.put$conversions_Value(compared$ref_ref_conversions_Named(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _88: Named.Named = Named.make$conversions_Value(data, 22); - const _90: Named.Named = Named.make$conversions_Value(data, 23); - Named.put$conversions_Value(compared$mut_conversions_Named(_88, _90, out), out); + const _100: Named.Named = Named.make$conversions_Value(data, 22); + const _102: Named.Named = Named.make$conversions_Value(data, 23); + Named.put$conversions_Value(compared$mut_conversions_Named(_100, _102, out), out); rs.byteVecPush(out, compared$ref_slice_conversions_Named(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: Named.Named | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: Named.Named | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - Named.put$conversions_Value(_106, out); + Named.put$conversions_Value(_118, out); } } @@ -5870,19 +5914,25 @@ export function referenced$u32(data: rs.ByteSlice, out: rs.ByteVec): void { borrowWrite$u32_mut_u32(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); const _65: rs.u32 = make$conversions_Value_u32(data, 25); borrowWrite$u32_mut_u32(rs.place(() => array[1], (value5) => array[1] = value5), _65); + let whole: rs.u32 = make$conversions_Value_u32(data, 26); + whole = make$conversions_Value_u32(data, 27); + put$conversions_Value_u32(whole, out); + const _74: rs.Vec = list; + const _77: rs.u32 = make$conversions_Value_u32(data, 28); + _74.items.push(_77); put$conversions_Value_u32(compared$ref_u32(array[0], array[1], out), out); put$conversions_Value_u32(compared$ref_ref_u32(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _88: rs.u32 = make$conversions_Value_u32(data, 22); - let _90: rs.u32 = make$conversions_Value_u32(data, 23); - put$conversions_Value_u32(compared$mut_u32(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + let _100: rs.u32 = make$conversions_Value_u32(data, 22); + let _102: rs.u32 = make$conversions_Value_u32(data, 23); + put$conversions_Value_u32(compared$mut_u32(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); rs.byteVecPush(out, compared$ref_slice_u32(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: rs.u32 | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.u32 | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_u32(_106, out); + put$conversions_Value_u32(_118, out); } } @@ -5920,19 +5970,25 @@ export function referenced$u64(data: rs.ByteSlice, out: rs.ByteVec): void { borrowWrite$u64_mut_u64(rs.place(() => list.items[at3], (value4) => list.items[at3] = value4), _60); const _65: rs.u64 = make$conversions_Value_u64(data, 25); borrowWrite$u64_mut_u64(rs.place(() => array[1], (value5) => array[1] = value5), _65); + let whole: rs.u64 = make$conversions_Value_u64(data, 26); + whole = make$conversions_Value_u64(data, 27); + put$conversions_Value_u64(whole, out); + const _74: rs.Vec = list; + const _77: rs.u64 = make$conversions_Value_u64(data, 28); + _74.items.push(_77); put$conversions_Value_u64(compared$ref_u64(array[0], array[1], out), out); put$conversions_Value_u64(compared$ref_ref_u64(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _88: rs.u64 = make$conversions_Value_u64(data, 22); - let _90: rs.u64 = make$conversions_Value_u64(data, 23); - put$conversions_Value_u64(compared$mut_u64(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + let _100: rs.u64 = make$conversions_Value_u64(data, 22); + let _102: rs.u64 = make$conversions_Value_u64(data, 23); + put$conversions_Value_u64(compared$mut_u64(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); rs.byteVecPush(out, compared$ref_slice_u64(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _106: rs.u64 | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.u64 | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_u64(_106, out); + put$conversions_Value_u64(_118, out); } } @@ -5969,19 +6025,23 @@ export function referenced$u8(data: rs.ByteSlice, out: rs.ByteVec): void { borrowWrite$u8_mut_u8(rs.place(() => list.data[at3], (value4) => list.data[at3] = value4), _60); const _65: rs.u8 = make$conversions_Value_u8(data, 25); borrowWrite$u8_mut_u8(rs.place(() => array[1], (value5) => array[1] = value5), _65); + let whole: rs.u8 = make$conversions_Value_u8(data, 26); + whole = make$conversions_Value_u8(data, 27); + put$conversions_Value_u8(whole, out); + rs.byteVecPush(list, make$conversions_Value_u8(data, 28)); put$conversions_Value_u8(compared$ref_u8(array[0], array[1], out), out); put$conversions_Value_u8(compared$ref_ref_u8(list.data[rs.idx(list, 1)], array[2], out), out); - let _88: rs.u8 = make$conversions_Value_u8(data, 22); - let _90: rs.u8 = make$conversions_Value_u8(data, 23); - put$conversions_Value_u8(compared$mut_u8(rs.place(() => _88, (value6) => _88 = value6), rs.place(() => _90, (value7) => _90 = value7), out).v, out); + let _100: rs.u8 = make$conversions_Value_u8(data, 22); + let _102: rs.u8 = make$conversions_Value_u8(data, 23); + put$conversions_Value_u8(compared$mut_u8(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); rs.byteVecPush(out, compared$ref_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 0), rs.byteSliceRange(rs.byteVecSlice(list), 0), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(rs.byteSliceView(rs.byteSliceFrom(array))), rs.iterSlice(rs.byteVecView(list))); while (true) { - const _106: rs.u8 | rs.Done = iter.next(); - if (_106 === rs.DONE) { + const _118: rs.u8 | rs.Done = iter.next(); + if (_118 === rs.DONE) { break; } - put$conversions_Value_u8(_106, out); + put$conversions_Value_u8(_118, out); } } diff --git a/ts/fixtures/lang/conversions/src/conversions.rs b/ts/fixtures/lang/conversions/src/conversions.rs index 02050cd43..b645da253 100644 --- a/ts/fixtures/lang/conversions/src/conversions.rs +++ b/ts/fixtures/lang/conversions/src/conversions.rs @@ -674,6 +674,11 @@ fn referenced(data: &[u8], out: &mut Vec) { borrow_put::(&mut list[1], out); borrow_write(&mut list[1], T::make(data, 24)); borrow_write(&mut array[1], T::make(data, 25)); + // std's own impls for any `T`, and through a `&mut` to a `&mut`. + let mut whole = T::make(data, 26); + *BorrowMut::::borrow_mut(&mut whole) = T::make(data, 27); + Borrow::::borrow(&whole).put(out); + BorrowMut::>::borrow_mut(&mut &mut list).push(T::make(data, 28)); compared(&array[0], &array[1], out).put(out); compared(&&list[1], &&array[2], out).put(out); compared(&mut T::make(data, 22), &mut T::make(data, 23), out).put(out); diff --git a/ts/src/lower/collections.rs b/ts/src/lower/collections.rs index 88c35b7f9..b27ea3fa8 100644 --- a/ts/src/lower/collections.rs +++ b/ts/src/lower/collections.rs @@ -163,15 +163,19 @@ pub fn call<'tcx>( } ("Borrow", "borrow", ..) | ("BorrowMut", "borrow_mut", ..) if let Some(t) = self_ty => { let by = library::targ(call.args, 1); - let value = match (same_key(b, t, by), arc_of(b, peel(b, t)), b.t.place_pointee(t)) { - (true, ..) => args.pop(), - (false, Some(inner), _) if same_key(b, inner, by) => args.pop().map(|v| v.member("value")), - // A `&mut` to a value JS copies, its `rs.Place`: what it holds for `borrow`, and - // itself for `borrow_mut`, whose receiver is given as what it points at. - (false, _, Some(inner)) if same_key(b, inner, by) => args.pop().map(|place| match name { - "borrow" => b.t.pointee_value(t, place), - _ => place, + // A `&mut` to a value JS copies is its `rs.Place`, which `borrow` reads. + let held = b.t.place_pointee(t).is_some_and(|inner| same_key(b, inner, by)); + let value = match arc_of(b, peel(b, t)) { + _ if held || same_key(b, t, by) => args.pop().map(|value| match name { + "borrow" if held => b.t.pointee_value(t, value), + // Given the place of its receiver, which a `&mut` holds. + "borrow_mut" if t.is_ref() => { + let receiver = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, t); + b.t.pointee_value(receiver, value) + } + _ => value, }), + Some(inner) if same_key(b, inner, by) => args.pop().map(|v| v.member("value")), _ => return Err(args), }; return Ok(value); diff --git a/ts/src/lower/pointer.rs b/ts/src/lower/pointer.rs index e7affe577..255b31af6 100644 --- a/ts/src/lower/pointer.rs +++ b/ts/src/lower/pointer.rs @@ -424,8 +424,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, the crate's own iterator's that its -/// `next` reads through, and a well-known crate's, such as a +/// whole `Result`, an iterator's that `by_ref` returns, what `borrow_mut` lends, 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>, @@ -438,6 +438,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") + || (owner.as_str(), name.as_str()) == ("BorrowMut", "borrow_mut") || 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 a hasher whose methods take it as it is. From de3c132115a331d2e03f332a3d9ad1bba24d7523 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Wed, 4 Nov 2026 09:48:42 -0800 Subject: [PATCH 4/5] fix(ts): keep the place of a reference BorrowMut lends as itself std's impl for any `T`, at a reference, lends the receiver's place, which holds the reference, rather than the place the reference points at. Co-Authored-By: Claude Opus 5.5 --- .../lang/conversions/expected/conversions.ts | 143 +++++++++++------- .../lang/conversions/src/conversions.rs | 4 + ts/src/lower/collections.rs | 8 +- 3 files changed, 100 insertions(+), 55 deletions(-) diff --git a/ts/fixtures/lang/conversions/expected/conversions.ts b/ts/fixtures/lang/conversions/expected/conversions.ts index 844a6cda8..0968c3af2 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.ts @@ -5585,19 +5585,23 @@ export function referenced$Option_u16(data: rs.ByteSlice, out: rs.ByteVec): void const _74: rs.Vec = list; const _77: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 28); _74.items.push(_77); + const other: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 29); + let r: rs.u16 | undefined = whole; + r = other; + put$conversions_Value_Option_u16(r, out); put$conversions_Value_Option_u16(compared$ref_Option_u16(array[0], array[1], out), out); put$conversions_Value_Option_u16(compared$ref_ref_Option_u16(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _100: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 22); - let _102: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); - put$conversions_Value_Option_u16(compared$mut_Option_u16(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); + let _107: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 22); + let _109: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); + put$conversions_Value_Option_u16(compared$mut_Option_u16(rs.place(() => _107, (value9) => _107 = value9), rs.place(() => _109, (value10) => _109 = value10), out).v, out); rs.byteVecPush(out, compared$ref_slice_Option_u16(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: rs.u16 | undefined | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.u16 | undefined | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_Option_u16(_118, out); + put$conversions_Value_Option_u16(_125, out); } } @@ -5641,19 +5645,23 @@ export function referenced$String(data: rs.ByteSlice, out: rs.ByteVec): void { const _74: rs.Vec = list; const _77: string = make$conversions_Value_String(data, 28); _74.items.push(_77); + const other: string = make$conversions_Value_String(data, 29); + let r: string = whole; + r = other; + put$conversions_Value_String(r, out); put$conversions_Value_String(compared$ref_String(array[0], array[1], out), out); put$conversions_Value_String(compared$ref_ref_String(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _100: string = make$conversions_Value_String(data, 22); - let _102: string = make$conversions_Value_String(data, 23); - put$conversions_Value_String(compared$mut_String(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); + let _107: string = make$conversions_Value_String(data, 22); + let _109: string = make$conversions_Value_String(data, 23); + put$conversions_Value_String(compared$mut_String(rs.place(() => _107, (value9) => _107 = value9), rs.place(() => _109, (value10) => _109 = value10), out).v, out); rs.byteVecPush(out, compared$ref_slice_String(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: string | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: string | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_String(_118, out); + put$conversions_Value_String(_125, out); } } @@ -5696,19 +5704,23 @@ export function referenced$Vec_u8(data: rs.ByteSlice, out: rs.ByteVec): void { const _74: rs.Vec = list; const _77: rs.ByteVec = make$conversions_Value_Vec_u8(data, 28); _74.items.push(_77); + const other: rs.ByteVec = make$conversions_Value_Vec_u8(data, 29); + let r: rs.ByteVec = whole; + r = other; + put$conversions_Value_Vec_u8(r, out); put$conversions_Value_Vec_u8(compared$ref_Vec_u8(array[0], array[1], out), out); put$conversions_Value_Vec_u8(compared$ref_ref_Vec_u8(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _100: rs.ByteVec = make$conversions_Value_Vec_u8(data, 22); - const _102: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); - put$conversions_Value_Vec_u8(compared$mut_Vec_u8(_100, _102, out), out); + const _107: rs.ByteVec = make$conversions_Value_Vec_u8(data, 22); + const _109: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); + put$conversions_Value_Vec_u8(compared$mut_Vec_u8(_107, _109, out), out); rs.byteVecPush(out, compared$ref_slice_Vec_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: rs.ByteVec | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.ByteVec | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_Vec_u8(_118, out); + put$conversions_Value_Vec_u8(_125, out); } } @@ -5749,17 +5761,21 @@ export function referenced$array3_u8(data: rs.ByteSlice, out: rs.ByteVec): void const _74: rs.Vec = list; const _77: Uint8Array = copy$array_u8(make$conversions_Value_array3_u8(data, 28)); _74.items.push(_77); + const other: Uint8Array = make$conversions_Value_array3_u8(data, 29); + let r: rs.ByteSlice = rs.byteSliceFrom(whole); + r = rs.byteSliceFrom(other); + put$conversions_Value_array3_u8(r, out); put$conversions_Value_array3_u8(compared$ref_array3_u8(rs.byteSliceFrom(array[0]), rs.byteSliceFrom(array[1]), out), out); put$conversions_Value_array3_u8(compared$ref_ref_array3_u8(rs.byteSliceFrom(list.items[rs.idx(list.items, 1)]), rs.byteSliceFrom(array[2]), out), out); put$conversions_Value_array3_u8(compared$mut_array3_u8(rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 22))), rs.byteSliceFrom(copy$array_u8(make$conversions_Value_array3_u8(data, 23))), out), out); rs.byteVecPush(out, compared$ref_slice_array3_u8(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterLend(rs.iterSlice(array), rs.byteSliceFrom), rs.iterLend(rs.iterSlice(list.items), rs.byteSliceFrom)); while (true) { - const _118: rs.ByteSlice | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.ByteSlice | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_array3_u8(_118, out); + put$conversions_Value_array3_u8(_125, out); } } @@ -5804,22 +5820,27 @@ export function referenced$conversions_Logged(data: rs.ByteSlice, out: rs.ByteVe const _74: rs.Vec = list; const _77: Logged.Logged = Logged.make$conversions_Value(data, 28); _74.items.push(_77); + const other: Logged.Logged = Logged.make$conversions_Value(data, 29); + let r: Logged.Logged = whole; + r = other; + Logged.put$conversions_Value(r, out); Logged.put$conversions_Value(compared$ref_conversions_Logged(array[0], array[1], out), out); Logged.put$conversions_Value(compared$ref_ref_conversions_Logged(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _100: Logged.Logged = Logged.make$conversions_Value(data, 22); - const _102: Logged.Logged = Logged.make$conversions_Value(data, 23); - Logged.put$conversions_Value(compared$mut_conversions_Logged(_100, _102, out), out); - _102[Symbol.dispose](); - _100[Symbol.dispose](); + const _107: Logged.Logged = Logged.make$conversions_Value(data, 22); + const _109: Logged.Logged = Logged.make$conversions_Value(data, 23); + Logged.put$conversions_Value(compared$mut_conversions_Logged(_107, _109, out), out); + _109[Symbol.dispose](); + _107[Symbol.dispose](); rs.byteVecPush(out, compared$ref_slice_conversions_Logged(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: Logged.Logged | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: Logged.Logged | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - Logged.put$conversions_Value(_118, out); + Logged.put$conversions_Value(_125, out); } + other[Symbol.dispose](); whole[Symbol.dispose](); rs.dropVec(list); rs.dropAll(array); @@ -5864,19 +5885,23 @@ export function referenced$conversions_Named(data: rs.ByteSlice, out: rs.ByteVec const _74: rs.Vec = list; const _77: Named.Named = Named.make$conversions_Value(data, 28); _74.items.push(_77); + const other: Named.Named = Named.make$conversions_Value(data, 29); + let r: Named.Named = whole; + r = other; + Named.put$conversions_Value(r, out); Named.put$conversions_Value(compared$ref_conversions_Named(array[0], array[1], out), out); Named.put$conversions_Value(compared$ref_ref_conversions_Named(list.items[rs.idx(list.items, 1)], array[2], out), out); - const _100: Named.Named = Named.make$conversions_Value(data, 22); - const _102: Named.Named = Named.make$conversions_Value(data, 23); - Named.put$conversions_Value(compared$mut_conversions_Named(_100, _102, out), out); + const _107: Named.Named = Named.make$conversions_Value(data, 22); + const _109: Named.Named = Named.make$conversions_Value(data, 23); + Named.put$conversions_Value(compared$mut_conversions_Named(_107, _109, out), out); rs.byteVecPush(out, compared$ref_slice_conversions_Named(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: Named.Named | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: Named.Named | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - Named.put$conversions_Value(_118, out); + Named.put$conversions_Value(_125, out); } } @@ -5920,19 +5945,23 @@ export function referenced$u32(data: rs.ByteSlice, out: rs.ByteVec): void { const _74: rs.Vec = list; const _77: rs.u32 = make$conversions_Value_u32(data, 28); _74.items.push(_77); + const other: rs.u32 = make$conversions_Value_u32(data, 29); + let r: rs.u32 = whole; + r = other; + put$conversions_Value_u32(r, out); put$conversions_Value_u32(compared$ref_u32(array[0], array[1], out), out); put$conversions_Value_u32(compared$ref_ref_u32(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _100: rs.u32 = make$conversions_Value_u32(data, 22); - let _102: rs.u32 = make$conversions_Value_u32(data, 23); - put$conversions_Value_u32(compared$mut_u32(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); + let _107: rs.u32 = make$conversions_Value_u32(data, 22); + let _109: rs.u32 = make$conversions_Value_u32(data, 23); + put$conversions_Value_u32(compared$mut_u32(rs.place(() => _107, (value9) => _107 = value9), rs.place(() => _109, (value10) => _109 = value10), out).v, out); rs.byteVecPush(out, compared$ref_slice_u32(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: rs.u32 | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.u32 | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_u32(_118, out); + put$conversions_Value_u32(_125, out); } } @@ -5976,19 +6005,23 @@ export function referenced$u64(data: rs.ByteSlice, out: rs.ByteVec): void { const _74: rs.Vec = list; const _77: rs.u64 = make$conversions_Value_u64(data, 28); _74.items.push(_77); + const other: rs.u64 = make$conversions_Value_u64(data, 29); + let r: rs.u64 = whole; + r = other; + put$conversions_Value_u64(r, out); put$conversions_Value_u64(compared$ref_u64(array[0], array[1], out), out); put$conversions_Value_u64(compared$ref_ref_u64(list.items[rs.idx(list.items, 1)], array[2], out), out); - let _100: rs.u64 = make$conversions_Value_u64(data, 22); - let _102: rs.u64 = make$conversions_Value_u64(data, 23); - put$conversions_Value_u64(compared$mut_u64(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); + let _107: rs.u64 = make$conversions_Value_u64(data, 22); + let _109: rs.u64 = make$conversions_Value_u64(data, 23); + put$conversions_Value_u64(compared$mut_u64(rs.place(() => _107, (value9) => _107 = value9), rs.place(() => _109, (value10) => _109 = value10), out).v, out); rs.byteVecPush(out, compared$ref_slice_u64(rs.sliceFrom(array), rs.sliceFrom(list.items), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(array), rs.iterSlice(list.items)); while (true) { - const _118: rs.u64 | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.u64 | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_u64(_118, out); + put$conversions_Value_u64(_125, out); } } @@ -6029,19 +6062,23 @@ export function referenced$u8(data: rs.ByteSlice, out: rs.ByteVec): void { whole = make$conversions_Value_u8(data, 27); put$conversions_Value_u8(whole, out); rs.byteVecPush(list, make$conversions_Value_u8(data, 28)); + const other: rs.u8 = make$conversions_Value_u8(data, 29); + let r: rs.u8 = whole; + r = other; + put$conversions_Value_u8(r, out); put$conversions_Value_u8(compared$ref_u8(array[0], array[1], out), out); put$conversions_Value_u8(compared$ref_ref_u8(list.data[rs.idx(list, 1)], array[2], out), out); - let _100: rs.u8 = make$conversions_Value_u8(data, 22); - let _102: rs.u8 = make$conversions_Value_u8(data, 23); - put$conversions_Value_u8(compared$mut_u8(rs.place(() => _100, (value8) => _100 = value8), rs.place(() => _102, (value9) => _102 = value9), out).v, out); + let _107: rs.u8 = make$conversions_Value_u8(data, 22); + let _109: rs.u8 = make$conversions_Value_u8(data, 23); + put$conversions_Value_u8(compared$mut_u8(rs.place(() => _107, (value9) => _107 = value9), rs.place(() => _109, (value10) => _109 = value10), out).v, out); rs.byteVecPush(out, compared$ref_slice_u8(rs.byteSliceRange(rs.byteSliceFrom(array), 0), rs.byteSliceRange(rs.byteVecSlice(list), 0), out).length & 0xff); const iter: rs.Iter = rs.iterChain(rs.iterSlice(rs.byteSliceView(rs.byteSliceFrom(array))), rs.iterSlice(rs.byteVecView(list))); while (true) { - const _118: rs.u8 | rs.Done = iter.next(); - if (_118 === rs.DONE) { + const _125: rs.u8 | rs.Done = iter.next(); + if (_125 === rs.DONE) { break; } - put$conversions_Value_u8(_118, out); + put$conversions_Value_u8(_125, out); } } diff --git a/ts/fixtures/lang/conversions/src/conversions.rs b/ts/fixtures/lang/conversions/src/conversions.rs index b645da253..a2353443e 100644 --- a/ts/fixtures/lang/conversions/src/conversions.rs +++ b/ts/fixtures/lang/conversions/src/conversions.rs @@ -679,6 +679,10 @@ fn referenced(data: &[u8], out: &mut Vec) { *BorrowMut::::borrow_mut(&mut whole) = T::make(data, 27); Borrow::::borrow(&whole).put(out); BorrowMut::>::borrow_mut(&mut &mut list).push(T::make(data, 28)); + let other = T::make(data, 29); + let mut r = &whole; + *BorrowMut::<&T>::borrow_mut(&mut r) = &other; + r.put(out); compared(&array[0], &array[1], out).put(out); compared(&&list[1], &&array[2], out).put(out); compared(&mut T::make(data, 22), &mut T::make(data, 23), out).put(out); diff --git a/ts/src/lower/collections.rs b/ts/src/lower/collections.rs index b27ea3fa8..27f76082b 100644 --- a/ts/src/lower/collections.rs +++ b/ts/src/lower/collections.rs @@ -168,8 +168,12 @@ pub fn call<'tcx>( let value = match arc_of(b, peel(b, t)) { _ if held || same_key(b, t, by) => args.pop().map(|value| match name { "borrow" if held => b.t.pointee_value(t, value), - // Given the place of its receiver, which a `&mut` holds. - "borrow_mut" if t.is_ref() => { + // Given the place of its receiver, which a `&mut` holds, but where it lends + // itself, as std's impl for any `T` does. + "borrow_mut" + if t.is_ref() + && tcx.erase_and_anonymize_regions(t) != tcx.erase_and_anonymize_regions(by) => + { let receiver = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, t); b.t.pointee_value(receiver, value) } From 8dcf6dafcf4467a9f8843574c2a7264907f369b8 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Wed, 4 Nov 2026 10:56:53 -0800 Subject: [PATCH 5/5] fix(ts): order only a `&mut`'s place by what it holds A raw pointer orders by its address, which `cmp_fn` refuses, rather than by what it points at. Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/reject/census.txt | 2 ++ ts/fixtures/reject/expected.txt | 2 ++ ts/fixtures/reject/src/pointers.rs | 6 ++++++ ts/fixtures/reject/ts.toml | 1 + ts/src/lower/collections.rs | 13 +++++++++++-- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ts/fixtures/reject/census.txt b/ts/fixtures/reject/census.txt index 6e4576b9a..49e780d9e 100644 --- a/ts/fixtures/reject/census.txt +++ b/ts/fixtures/reject/census.txt @@ -230,6 +230,8 @@ fixtures/reject/src/pointers.rs:pointers_apart+10:26: `offset_from` between a po fixtures/reject/src/pointers.rs:pointers_apart+11:24: `offset_from` between a pointer into an array of this body's own and one into an array of this body's own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:pointers_apart+12:23: `offset_from` between a pointer into an array of this body's own and one into an array of this body's own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:pointers_apart+14:21: `offset_from` between a pointer into a shared slice JS copies and one into a value in no array, which JS keeps in different arrays +fixtures/reject/src/pointers.rs:pointers_ordered+2:2: comparing pointers to `u32`, each a place JS makes of its own +fixtures/reject/src/pointers.rs:pointers_ordered+2:2: ordering `*const u32` by its address, which JS has no counterpart of, in `std::cmp::max` fixtures/reject/src/pointers.rs:put_replaced+2:10: a raw pointer to `(u32, u32)` in `pointers::Plain`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:range_of+1:2: a raw pointer to `(u32, u32)` in `pointers::Window`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:rc_raw_bytes+1:11: an `Rc`'s raw pointer to `[u8; 4]`, which JS makes anew each time diff --git a/ts/fixtures/reject/expected.txt b/ts/fixtures/reject/expected.txt index 96445c56c..8fe260fff 100644 --- a/ts/fixtures/reject/expected.txt +++ b/ts/fixtures/reject/expected.txt @@ -232,6 +232,8 @@ fixtures/reject/src/pointers.rs:pointers_apart+10:26: `offset_from` between a po fixtures/reject/src/pointers.rs:pointers_apart+11:24: `offset_from` between a pointer into an array of this body's own and one into an array of this body's own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:pointers_apart+12:23: `offset_from` between a pointer into an array of this body's own and one into an array of this body's own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:pointers_apart+14:21: `offset_from` between a pointer into a shared slice JS copies and one into a value in no array, which JS keeps in different arrays +fixtures/reject/src/pointers.rs:pointers_ordered+2:2: comparing pointers to `u32`, each a place JS makes of its own +fixtures/reject/src/pointers.rs:pointers_ordered+2:2: ordering `*const u32` by its address, which JS has no counterpart of, in `std::cmp::max` fixtures/reject/src/pointers.rs:put_replaced+2:10: a raw pointer to `(u32, u32)` in `pointers::Plain`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:range_of+1:2: a raw pointer to `(u32, u32)` in `pointers::Window`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:rc_raw_bytes+1:11: an `Rc`'s raw pointer to `[u8; 4]`, which JS makes anew each time diff --git a/ts/fixtures/reject/src/pointers.rs b/ts/fixtures/reject/src/pointers.rs index 5c1001f3f..e74d8cf63 100644 --- a/ts/fixtures/reject/src/pointers.rs +++ b/ts/fixtures/reject/src/pointers.rs @@ -534,3 +534,9 @@ pub fn rc_raw_bytes(p: *const [u8; 4]) -> u8 { pub fn arc_from_borrow(n: &u32) -> u32 { unsafe { *std::sync::Arc::from_raw(std::ptr::from_ref(n)) } } + +/// The greater of two pointers to numbers, which orders by their addresses. +pub fn pointers_ordered(a: &u32, b: &u32) -> bool { + let (p, q) = (std::ptr::from_ref(a), std::ptr::from_ref(b)); + std::cmp::max(p, q) == p +} diff --git a/ts/fixtures/reject/ts.toml b/ts/fixtures/reject/ts.toml index 37e1692d3..651847971 100644 --- a/ts/fixtures/reject/ts.toml +++ b/ts/fixtures/reject/ts.toml @@ -164,6 +164,7 @@ roots = [ "pointers::pointer_pushed", "pointers::pointer_returned", "pointers::pointers_apart", + "pointers::pointers_ordered", "pointers::put_replaced", "pointers::range_of", "pointers::range_replaced", diff --git a/ts/src/lower/collections.rs b/ts/src/lower/collections.rs index 27f76082b..6051ed934 100644 --- a/ts/src/lower/collections.rs +++ b/ts/src/lower/collections.rs @@ -74,7 +74,7 @@ pub fn call<'tcx>( // `<=`, and `>`, and of `&mut`s to values JS copies, their `rs.Place`s, by what they // hold, as std's impls for a `&mut` forward them. ("Ord", "max" | "min" | "clamp", ..) if let Some(t) = self_ty => { - let held = b.t.place_pointee(t); + let held = mut_place(b, t); let t = peel_ord(b, held.unwrap_or(t), false); let own = matches!(t.kind(), ty::Adt(adt, _) if b.t.own(adt.did())) || pointee(b, t).is_some(); if !(std_key(b, t) || own) || held.is_none() && Int::of(t).is_some() { @@ -164,7 +164,7 @@ pub fn call<'tcx>( ("Borrow", "borrow", ..) | ("BorrowMut", "borrow_mut", ..) if let Some(t) = self_ty => { let by = library::targ(call.args, 1); // A `&mut` to a value JS copies is its `rs.Place`, which `borrow` reads. - let held = b.t.place_pointee(t).is_some_and(|inner| same_key(b, inner, by)); + let held = mut_place(b, t).is_some_and(|inner| same_key(b, inner, by)); let value = match arc_of(b, peel(b, t)) { _ if held || same_key(b, t, by) => args.pop().map(|value| match name { "borrow" if held => b.t.pointee_value(t, value), @@ -541,6 +541,15 @@ fn peel<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } } +/// What `ty`, a `&mut` that is an `rs.Place`, points at; not a raw pointer, which orders +/// by its address. +fn mut_place<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option> { + match ty.kind() { + ty::Ref(_, _, ty::Mutability::Mut) => b.t.place_pointee(ty), + _ => None, + } +} + /// What `ty` points at, if JS holds it as that: `peel`'s one step. fn pointee<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option> { match ty.kind() {