diff --git a/quest/m3/README.md b/quest/m3/README.md index cbb5b1a3c..3046ee661 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -45,7 +45,6 @@ memory model for values whose address is reinterpreted, without a consumer. - [Unsafe code the translator can model](/quest/m3/ts-unsafe/README.md) - a dependency using only `unsafe` the translator can model translates from source - [Waiting: drop the lang fixture's mul_add allowance](/quest/m3/ts-fma-allowance.md) - the differential fails on any `mul_add` difference again once wasm32's `fma` rounds exactly - [Waiting: type-check in process with tsrs](/quest/m3/ts-tsrs.md) - rust2-ts checks bindings through tsrs instead of `tsc` once it is a stable library -- [Parts of arrays without arrayView](/quest/m3/ts-slice-object.md) - a `&mut [T; N]` to part of an array is taken where it is, with no `Proxy` - [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - no runtime `rust2-ts:` error where native Rust goes on: an exact slower path, or a refusal at translation - [rust2-ts with no ts.toml](/quest/m3/ts-configless.md) - a crate's whole `pub` API translates with no config and no bound items - [Browser APIs through wasm-bindgen](/quest/m3/ts-wasm-bindgen/README.md) - web-sys and js-sys imports become direct JS calls, so idiomatic crates such as web-rs's web-codecs translate as stock crates diff --git a/quest/m3/ts-runtime-throws.md b/quest/m3/ts-runtime-throws.md index f3aa2146c..af4fad7bf 100644 --- a/quest/m3/ts-runtime-throws.md +++ b/quest/m3/ts-runtime-throws.md @@ -45,7 +45,7 @@ addresses stay refused (decided 2026-11-07 in [the model epic](/quest/m2/ts-mode ✅ Decided with the maintainer on 2026-11-06 in [moq-dev/rust2#608](https://github.com/moq-dev/rust2/pull/608): comparing `*const [T]` of -values JS copies moved here from [rs.Slice](/quest/m3/ts-slice-object.md). The options +values JS copies moved here from rs.Slice's quest. The options were to wait on rs.String ([moq-dev/rust2#574](https://github.com/moq-dev/rust2/pull/574)) and run only if `&str` shares its bytes, or to move it here with the other comparisons left refused (picked). Its only consumer in moq-net is form_urlencoded 1.2.2's `src/lib.rs:417`, diff --git a/quest/m3/ts-slice-object.md b/quest/m3/ts-slice-object.md deleted file mode 100644 index 2c9188be3..000000000 --- a/quest/m3/ts-slice-object.md +++ /dev/null @@ -1,55 +0,0 @@ -# [M] Parts of arrays without arrayView - -## Goal - -[rust2-ts](/ts/README.md) holds a slice of arrays as an `rs.ArraySlice` of the slice each array -is, with no `Proxy`. What remains is the runtime's `arrayView`, a `Proxy` JS array over -part of another, which `rs.sliceView` makes where a `&mut [T; N]` to part of an array is -taken whole as a JS array: by `mem::replace` and `mem::swap` of an element of a slice of -arrays, `Cell::from_mut` of one, std's mappings given one to write through, and a raw -pointer's `as_mut` or `Box::from_raw`. Each takes the slice where it is instead, or a -copy written back as `rs.arraySliceBy` writes arrays back, and `arrayView` and its `View` traps -go. Proven by differential tests against native Rust. - -## Plan - -✅ Decided with the maintainer on 2026-11-06 in -[moq-dev/rust2#608](https://github.com/moq-dev/rust2/pull/608), which made `rs.ArraySlice`: - -1. How a `&mut [[T; N]]` holds its arrays: - - ✅ (a) A runtime type for every slice of arrays, nested or flat, whose element `i` is - the slice of array `i`, which replaces the `Runs` and `ByteRuns` `Proxy` views and - `arrayView`. - - (b) Bytes only: `as_chunks_mut` makes eager `subarray` views, keeping the `Proxy` - path for other elements. - - (c) Keep the `Proxy` views and drop the item. -2. `slice::from_mut` of a `&mut u8`: kept, deferred to a quest of its own, since done - ([moq-dev/rust2#660](https://github.com/moq-dev/rust2/pull/660)). -3. Comparing `*const [T]` of values JS copies: moved to - [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md). - -✅ Decided with the maintainer on 2026-11-07 at the round-3 design checkpoint of -[moq-dev/rust2#608](https://github.com/moq-dev/rust2/pull/608): - -4. Conversions that copied arrays where Rust borrows them: ✅ continue, with local fixes - (rejected: merge as is; `rs.ArraySlice` only for what `as_chunks` splits, keeping - `rs.Slice` for other slices of arrays; drop). Where each array of an array slice is - a JS array of its own, `rs.arraySliceItems` slices the list of them rather than copying - each, so a std callback's `ptr::eq` sees the array it was lent, and `join` reads its - array separator without copying it, since it clones it anyway. The arrays `as_chunks` - splits from one flat slice have none of their own, so a callback still gets a copy: - that `ptr::eq` gap moved to [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md). -5. The type's name: ✅ `rs.ArraySlice`, as `rs.ByteSlice` and `rs.RawSlice` are named, - with its helpers `rs.arraySlice*` (rejected: `rs.Slices`, `rs.Chunks`, keep `rs.Runs`). - -Decided with the maintainer on 2026-11-03: Rust types the runtime can't hold as std's do -get a runtime wrapper, converted at API boundaries, rather than a JS native type -([#555](https://github.com/moq-dev/rust2/pull/555) made `Vec` one). - -`rs.replaceIn` and `rs.cellIn` of a JS array write a whole value into it, and copy its -elements to a depth where a write lands in them; a slice's form needs the same, as -`rs.arraySliceReplace` and `rs.cellOfArraySlice` do for arrays. A raw pointer to an array of arrays -that std's mapping gives back as a reference is refused today. - -Public API: the translator's output and what a hand-written caller passes for a slice of -arrays. diff --git a/ts/fixtures/lang/conversions/expected/conversions.ts b/ts/fixtures/lang/conversions/expected/conversions.ts index 14bbc791f..a3aa0d3aa 100644 --- a/ts/fixtures/lang/conversions/expected/conversions.ts +++ b/ts/fixtures/lang/conversions/expected/conversions.ts @@ -370,7 +370,7 @@ export function cloneFromParam$array1_u8(to: rs.ByteSlice, from: rs.ByteSlice): /** `clone_from` through a `&mut` whose place only the caller knows. */ export function cloneFromParam$array2_u32(to: rs.Slice, from: rs.Slice): void { - rs.replaceIn(rs.sliceView(to), rs.sliceToArray(from)); + rs.sliceReplaceAll(to, rs.sliceToArray(from)); } /** `clone_from` through a `&mut` whose place only the caller knows. */ @@ -440,7 +440,7 @@ export function cloneIntoParam$array1_u8(from: rs.ByteSlice, to: rs.ByteSlice): /** `clone_into` through a `&mut` whose place only the caller knows. */ export function cloneIntoParam$array2_u32(from: rs.Slice, to: rs.Slice): void { - rs.replaceIn(rs.sliceView(to), rs.sliceToArray(from)); + rs.sliceReplaceAll(to, rs.sliceToArray(from)); } /** `clone_into` through a `&mut` whose place only the caller knows. */ @@ -557,7 +557,7 @@ export function writeFirst$array2_u32(s: rs.ArraySlice>, value: value = copy$array_u32(value); rs.idx(s, 0); const _8: rs.u32[] = copy$array_u32(value.slice()); - const old: rs.u32[] = rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), _8); + const old: rs.u32[] = rs.sliceReplaceAll(rs.arraySliceAt(s, 0), _8); const _10: rs.u32[] = value; rs.idx(s, 0); rs.sliceSet(rs.arraySliceAt(s, 0), _10); @@ -661,25 +661,25 @@ export function writeFirst$u8(s: rs.ByteSlice, value: rs.u8): rs.u8 { /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$Option_u16(s: rs.ArraySlice>, value: Array): Array { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), copy$array_Option_u16(value)); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), copy$array_Option_u16(value)); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$String(s: rs.ArraySlice>, value: rs.String[]): rs.String[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), value, 1); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), value, 1); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$Vec_u32(s: rs.ArraySlice>>, value: rs.Vec[]): rs.Vec[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), value, 1); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), value, 1); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$Vec_u8(s: rs.ArraySlice>, value: rs.ByteVec[]): rs.ByteVec[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), value, 1); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), value, 1); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ @@ -715,25 +715,25 @@ export function replaceFirst$array40_u8(s: rs.ArraySlice>, value: Logged.Logged[]): Logged.Logged[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), value, 1); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), value, 1); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$conversions_Named(s: rs.ArraySlice>, value: Named.Named[]): Named.Named[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), value, 1); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), value, 1); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$u32(s: rs.ArraySlice>, value: rs.u32[]): rs.u32[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), copy$array_u32(value)); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), copy$array_u32(value)); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ export function replaceFirst$u64(s: rs.ArraySlice>, value: rs.u64[]): rs.u64[] { rs.idx(s, 0); - return rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), copy$array_u64(value)); + return rs.sliceReplaceAll(rs.arraySliceAt(s, 0), copy$array_u64(value)); } /** `mem::replace` of the first array, as a function given any slice of them makes it. */ @@ -785,14 +785,14 @@ export function lentParam$Option_u16(to: rs.Place, data: rs. const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: Array = [make$conversions_Value_Option_u16(data, 22)]; - put$conversions_Value_Option_u16(rs.replaceIn(rs.sliceView(a), _77)[0], out); + put$conversions_Value_Option_u16(rs.sliceReplaceAll(a, _77)[0], out); let by: rs.u16 | undefined = make$conversions_Value_Option_u16(data, 23); rs.idx(s, 0); const borrowed3 = s.start; let r: rs.Place = rs.place(() => s.data[borrowed3], (value2) => s.data[borrowed3] = value2); const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value3) => r = value3)); const _91: rs.Place[] = [rs.place(() => by, (value4) => by = value4)]; - rs.replaceIn(rs.sliceView(_89), _91)[0].v = make$conversions_Value_Option_u16(data, 24); + rs.sliceReplaceAll(_89, _91)[0].v = make$conversions_Value_Option_u16(data, 24); put$conversions_Value_Option_u16(r.v, out); rs.idx(s, 0); put$conversions_Value_Option_u16(s.data[s.start], out); @@ -803,10 +803,10 @@ export function lentParam$Option_u16(to: rs.Place, data: rs. rs.idx(s, 0); const borrowed6 = s.data; const borrowed7 = s.start; - const _114: rs.Cell> = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))))); + const _114: rs.Cell> = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))); const _121: Array = [make$conversions_Value_Option_u16(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer); rs.sliceSet(pointer, _121); put$conversions_Value_Option_u16(old6[0], out); rs.idx(s, 0); @@ -816,7 +816,12 @@ export function lentParam$Option_u16(to: rs.Place, data: rs. rs.idx(s, 0); const borrowed10 = s.data; const borrowed11 = s.start; - put$conversions_Value_Option_u16(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)), [[make$conversions_Value_Option_u16(data, 28)]])[0][0], out); + const _147: rs.Cell[]> = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)); + const _148: Array[] = [[make$conversions_Value_Option_u16(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_Option_u16(old7[0][0], out); rs.idx(s, 0); s.data[s.start] = other; rs.idx(s, 0); @@ -855,13 +860,13 @@ export function lentParam$String(to: rs.String, data: rs.ByteSlice, out: rs.Byte const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: rs.String[] = [make$conversions_Value_String(data, 22)]; - put$conversions_Value_String(rs.replaceIn(rs.sliceView(a), _77, 1)[0], out); + put$conversions_Value_String(rs.sliceReplaceAll(a, _77, 1)[0], out); const by: rs.String = make$conversions_Value_String(data, 23); rs.idx(s, 0); let r: rs.String = s.data[s.start]; const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); const _91: rs.String[] = [by]; - Object.assign(rs.replaceIn(rs.sliceView(_89), _91)[0], make$conversions_Value_String(data, 24)); + Object.assign(rs.sliceReplaceAll(_89, _91)[0], make$conversions_Value_String(data, 24)); put$conversions_Value_String(r, out); rs.idx(s, 0); put$conversions_Value_String(s.data[s.start], out); @@ -870,10 +875,10 @@ export function lentParam$String(to: rs.String, data: rs.ByteSlice, out: rs.Byte rs.idx(s, 0); const borrowed3 = s.data; const borrowed4 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))); const _121: rs.String[] = [make$conversions_Value_String(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer), 1); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer, 1); rs.sliceSet(pointer, _121); put$conversions_Value_String(old6[0], out); rs.idx(s, 0); @@ -883,7 +888,12 @@ export function lentParam$String(to: rs.String, data: rs.ByteSlice, out: rs.Byte rs.idx(s, 0); const borrowed7 = s.data; const borrowed8 = s.start; - put$conversions_Value_String(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy), [[make$conversions_Value_String(data, 28)]])[0][0], out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy); + const _148: rs.String[][] = [[make$conversions_Value_String(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2, rs.objectCopy); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_String(old7[0][0], out); rs.idx(s, 0); s.data[s.start] = rs.stringCloneFrom(s.data[s.start], other); rs.idx(s, 0); @@ -922,13 +932,13 @@ export function lentParam$Vec_u32(to: rs.Vec, data: rs.ByteSlice, out: r const borrowed2 = s.start; const a: rs.Slice> = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: rs.Vec[] = [make$conversions_Value_Vec_u32(data, 22)]; - put$conversions_Value_Vec_u32(rs.replaceIn(rs.sliceView(a), _77, 1)[0], out); + put$conversions_Value_Vec_u32(rs.sliceReplaceAll(a, _77, 1)[0], out); const by: rs.Vec = make$conversions_Value_Vec_u32(data, 23); rs.idx(s, 0); let r: rs.Vec = s.data[s.start]; const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); const _91: rs.Vec[] = [by]; - Object.assign(rs.replaceIn(rs.sliceView(_89), _91)[0], make$conversions_Value_Vec_u32(data, 24)); + Object.assign(rs.sliceReplaceAll(_89, _91)[0], make$conversions_Value_Vec_u32(data, 24)); put$conversions_Value_Vec_u32(r, out); rs.idx(s, 0); put$conversions_Value_Vec_u32(s.data[s.start], out); @@ -937,10 +947,10 @@ export function lentParam$Vec_u32(to: rs.Vec, data: rs.ByteSlice, out: r rs.idx(s, 0); const borrowed3 = s.data; const borrowed4 = s.start; - const _114: rs.Cell[]> = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))))); + const _114: rs.Cell[]> = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))); const _121: rs.Vec[] = [make$conversions_Value_Vec_u32(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer), 1); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer, 1); rs.sliceSet(pointer, _121); put$conversions_Value_Vec_u32(old6[0], out); rs.idx(s, 0); @@ -950,7 +960,12 @@ export function lentParam$Vec_u32(to: rs.Vec, data: rs.ByteSlice, out: r rs.idx(s, 0); const borrowed7 = s.data; const borrowed8 = s.start; - put$conversions_Value_Vec_u32(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy), [[make$conversions_Value_Vec_u32(data, 28)]])[0][0], out); + const _147: rs.Cell[][]> = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy); + const _148: rs.Vec[][] = [[make$conversions_Value_Vec_u32(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2, rs.objectCopy); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_Vec_u32(old7[0][0], out); rs.idx(s, 0); rs.vecCloneFrom(s.data[s.start], other, 4); rs.idx(s, 0); @@ -989,13 +1004,13 @@ export function lentParam$Vec_u8(to: rs.ByteVec, data: rs.ByteSlice, out: rs.Byt const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: rs.ByteVec[] = [make$conversions_Value_Vec_u8(data, 22)]; - put$conversions_Value_Vec_u8(rs.replaceIn(rs.sliceView(a), _77, 1)[0], out); + put$conversions_Value_Vec_u8(rs.sliceReplaceAll(a, _77, 1)[0], out); const by: rs.ByteVec = make$conversions_Value_Vec_u8(data, 23); rs.idx(s, 0); let r: rs.ByteVec = s.data[s.start]; const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); const _91: rs.ByteVec[] = [by]; - Object.assign(rs.replaceIn(rs.sliceView(_89), _91)[0], make$conversions_Value_Vec_u8(data, 24)); + Object.assign(rs.sliceReplaceAll(_89, _91)[0], make$conversions_Value_Vec_u8(data, 24)); put$conversions_Value_Vec_u8(r, out); rs.idx(s, 0); put$conversions_Value_Vec_u8(s.data[s.start], out); @@ -1004,10 +1019,10 @@ export function lentParam$Vec_u8(to: rs.ByteVec, data: rs.ByteSlice, out: rs.Byt rs.idx(s, 0); const borrowed3 = s.data; const borrowed4 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))); const _121: rs.ByteVec[] = [make$conversions_Value_Vec_u8(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer), 1); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer, 1); rs.sliceSet(pointer, _121); put$conversions_Value_Vec_u8(old6[0], out); rs.idx(s, 0); @@ -1017,7 +1032,12 @@ export function lentParam$Vec_u8(to: rs.ByteVec, data: rs.ByteSlice, out: rs.Byt rs.idx(s, 0); const borrowed7 = s.data; const borrowed8 = s.start; - put$conversions_Value_Vec_u8(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy), [[make$conversions_Value_Vec_u8(data, 28)]])[0][0], out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), rs.objectCopy); + const _148: rs.ByteVec[][] = [[make$conversions_Value_Vec_u8(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2, rs.objectCopy); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_Vec_u8(old7[0][0], out); rs.idx(s, 0); rs.byteVecCloneFrom(s.data[s.start], other); rs.idx(s, 0); @@ -1058,7 +1078,7 @@ export function lentParam$array0_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: r let r: rs.ByteSlice = rs.arraySliceAt(s, 0); const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value) => r = value)); const _91: rs.ByteSlice[] = [rs.byteSliceFrom(by)]; - const _88: rs.ByteSlice[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.ByteSlice[] = rs.sliceReplaceAll(_89, _91); const _93: Uint8Array = copy$array_u8(make$conversions_Value_array0_u8(data, 24)); _88[0].data.set(_93, _88[0].start); put$conversions_Value_array0_u8(r, out); @@ -1132,7 +1152,7 @@ export function lentParam$array1_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: r let r: rs.ByteSlice = rs.arraySliceAt(s, 0); const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value) => r = value)); const _91: rs.ByteSlice[] = [rs.byteSliceFrom(by)]; - const _88: rs.ByteSlice[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.ByteSlice[] = rs.sliceReplaceAll(_89, _91); const _93: Uint8Array = copy$array_u8(make$conversions_Value_array1_u8(data, 24)); _88[0].data.set(_93, _88[0].start); put$conversions_Value_array1_u8(r, out); @@ -1146,11 +1166,21 @@ export function lentParam$array1_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: r rs.byteSliceSet(pointer, _111); put$conversions_Value_array1_u8(rs.byteSliceFrom(old6), out); rs.idx(s, 0); - put$conversions_Value_array1_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 1)), [copy$array_u8(make$conversions_Value_array1_u8(data, 26))])[0]), out); + const _114: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 1)); + const _121: Uint8Array[] = [copy$array_u8(make$conversions_Value_array1_u8(data, 26))]; + const pointer2 = rs.cellArray(_114, rs.arraySliceOf(rs.byteSliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _121); + put$conversions_Value_array1_u8(rs.byteSliceFrom(old7[0]), out); rs.idx(s, 0); put$conversions_Value_array1_u8(rs.byteSliceFrom(replaceFirst$array1_u8(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 1), 1), [make$conversions_Value_array1_u8(data, 27)])[0]), out); rs.idx(s, 0); - put$conversions_Value_array1_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 1), 1)), [[copy$array_u8(make$conversions_Value_array1_u8(data, 28))]])[0][0]), out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 1), 1)); + const _148: Uint8Array[][] = [[copy$array_u8(make$conversions_Value_array1_u8(data, 28))]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.arraySliceOf(rs.byteSliceFrom))); + const old8 = rs.arraySliceCopy(pointer3); + rs.arraySliceSet(pointer3, _148); + put$conversions_Value_array1_u8(rs.byteSliceFrom(old8[0][0]), out); rs.idx(s, 0); const _159: rs.ByteSlice = rs.byteSliceFrom(other); const slice7 = rs.arraySliceAt(s, 0); @@ -1171,24 +1201,24 @@ export function lentParam$array2_u32(to: rs.Slice, data: rs.ByteSlice, o const other: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 19)); rs.idx(s, 0); const _16: rs.Slice = rs.sliceFrom(other); - rs.sliceSet(_16, rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), rs.sliceToArray(_16))); + rs.sliceSet(_16, rs.sliceReplaceAll(rs.arraySliceAt(s, 0), rs.sliceToArray(_16))); put$conversions_Value_array2_u32(rs.sliceFrom(other), out); const _20: rs.Slice = rs.sliceFrom(other); rs.idx(s, 0); const slice2 = rs.arraySliceAt(s, 0); - rs.sliceSet(slice2, rs.replaceIn(rs.sliceView(_20), rs.sliceToArray(slice2))); + rs.sliceSet(slice2, rs.sliceReplaceAll(_20, rs.sliceToArray(slice2))); put$conversions_Value_array2_u32(rs.sliceFrom(other), out); const t: rs.ArraySlice> = rs.arraySliceFrom(rs.vecFrom(copy$array_array2_u32([make$conversions_Value_array2_u32(data, 20), make$conversions_Value_array2_u32(data, 21)]).map(copy$array_u32)).items, rs.sliceFrom); rs.idx(s, 0); rs.idx(t, 1); const slice3 = rs.arraySliceAt(s, 0); const slice4 = rs.arraySliceAt(t, 1); - rs.sliceSet(slice4, rs.replaceIn(rs.sliceView(slice3), rs.sliceToArray(slice4))); + rs.sliceSet(slice4, rs.sliceReplaceAll(slice3, rs.sliceToArray(slice4))); rs.idx(t, 0); rs.idx(s, 0); const slice5 = rs.arraySliceAt(t, 0); const slice6 = rs.arraySliceAt(s, 0); - rs.sliceSet(slice6, rs.replaceIn(rs.sliceView(slice5), rs.sliceToArray(slice6))); + rs.sliceSet(slice6, rs.sliceReplaceAll(slice5, rs.sliceToArray(slice6))); rs.idx(t, 0); put$conversions_Value_array2_u32(rs.arraySliceAt(t, 0), out); rs.idx(t, 1); @@ -1202,28 +1232,38 @@ export function lentParam$array2_u32(to: rs.Slice, data: rs.ByteSlice, o let r: rs.Slice = rs.arraySliceAt(s, 0); const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value) => r = value)); const _91: rs.Slice[] = [rs.sliceFrom(by)]; - const _88: rs.Slice[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.Slice[] = rs.sliceReplaceAll(_89, _91); const _93: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 24)); rs.sliceSet(_88[0], _93); put$conversions_Value_array2_u32(r, out); rs.idx(s, 0); put$conversions_Value_array2_u32(rs.arraySliceAt(s, 0), out); rs.idx(s, 0); - const _105: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.arraySliceAt(s, 0)))); + const _105: rs.Cell = rs.cellOfSlice(rs.arraySliceAt(s, 0)); const _111: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 25)); - const pointer = rs.sliceFrom(_105.v); - const old6 = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(_105, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer); rs.sliceSet(pointer, _111); put$conversions_Value_array2_u32(rs.sliceFrom(old6), out); rs.idx(s, 0); - put$conversions_Value_array2_u32(rs.sliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 2)), [copy$array_u32(make$conversions_Value_array2_u32(data, 26))])[0]), out); + const _114: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 2)); + const _121: rs.u32[][] = [copy$array_u32(make$conversions_Value_array2_u32(data, 26))]; + const pointer2 = rs.cellArray(_114, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _121); + put$conversions_Value_array2_u32(rs.sliceFrom(old7[0]), out); rs.idx(s, 0); put$conversions_Value_array2_u32(rs.sliceFrom(replaceFirst$array2_u32(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 2), 1), [make$conversions_Value_array2_u32(data, 27)])[0]), out); rs.idx(s, 0); - put$conversions_Value_array2_u32(rs.sliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 2), 1)), [[copy$array_u32(make$conversions_Value_array2_u32(data, 28))]])[0][0]), out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 2), 1)); + const _148: rs.u32[][][] = [[copy$array_u32(make$conversions_Value_array2_u32(data, 28))]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.arraySliceOf(rs.sliceFrom))); + const old8 = rs.arraySliceCopy(pointer3); + rs.arraySliceSet(pointer3, _148); + put$conversions_Value_array2_u32(rs.sliceFrom(old8[0][0]), out); rs.idx(s, 0); const _159: rs.Slice = rs.sliceFrom(other); - rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), rs.sliceToArray(_159)); + rs.sliceReplaceAll(rs.arraySliceAt(s, 0), rs.sliceToArray(_159)); rs.idx(s, 0); put$conversions_Value_array2_u32(rs.arraySliceAt(s, 0), out); } @@ -1280,7 +1320,7 @@ export function lentParam$array3_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: r let r: rs.ByteSlice = rs.arraySliceAt(s, 0); const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value) => r = value)); const _91: rs.ByteSlice[] = [rs.byteSliceFrom(by)]; - const _88: rs.ByteSlice[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.ByteSlice[] = rs.sliceReplaceAll(_89, _91); const _93: Uint8Array = copy$array_u8(make$conversions_Value_array3_u8(data, 24)); _88[0].data.set(_93, _88[0].start); put$conversions_Value_array3_u8(r, out); @@ -1294,11 +1334,21 @@ export function lentParam$array3_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: r rs.byteSliceSet(pointer, _111); put$conversions_Value_array3_u8(rs.byteSliceFrom(old6), out); rs.idx(s, 0); - put$conversions_Value_array3_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 3)), [copy$array_u8(make$conversions_Value_array3_u8(data, 26))])[0]), out); + const _114: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 3)); + const _121: Uint8Array[] = [copy$array_u8(make$conversions_Value_array3_u8(data, 26))]; + const pointer2 = rs.cellArray(_114, rs.arraySliceOf(rs.byteSliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _121); + put$conversions_Value_array3_u8(rs.byteSliceFrom(old7[0]), out); rs.idx(s, 0); put$conversions_Value_array3_u8(rs.byteSliceFrom(replaceFirst$array3_u8(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 3), 1), [make$conversions_Value_array3_u8(data, 27)])[0]), out); rs.idx(s, 0); - put$conversions_Value_array3_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 3), 1)), [[copy$array_u8(make$conversions_Value_array3_u8(data, 28))]])[0][0]), out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 3), 1)); + const _148: Uint8Array[][] = [[copy$array_u8(make$conversions_Value_array3_u8(data, 28))]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.arraySliceOf(rs.byteSliceFrom))); + const old8 = rs.arraySliceCopy(pointer3); + rs.arraySliceSet(pointer3, _148); + put$conversions_Value_array3_u8(rs.byteSliceFrom(old8[0][0]), out); rs.idx(s, 0); const _159: rs.ByteSlice = rs.byteSliceFrom(other); const slice7 = rs.arraySliceAt(s, 0); @@ -1359,7 +1409,7 @@ export function lentParam$array40_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: let r: rs.ByteSlice = rs.arraySliceAt(s, 0); const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value) => r = value)); const _91: rs.ByteSlice[] = [rs.byteSliceFrom(by)]; - const _88: rs.ByteSlice[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.ByteSlice[] = rs.sliceReplaceAll(_89, _91); const _93: Uint8Array = copy$array_u8(make$conversions_Value_array40_u8(data, 24)); _88[0].data.set(_93, _88[0].start); put$conversions_Value_array40_u8(r, out); @@ -1373,11 +1423,21 @@ export function lentParam$array40_u8(to: rs.ByteSlice, data: rs.ByteSlice, out: rs.byteSliceSet(pointer, _111); put$conversions_Value_array40_u8(rs.byteSliceFrom(old6), out); rs.idx(s, 0); - put$conversions_Value_array40_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 40)), [copy$array_u8(make$conversions_Value_array40_u8(data, 26))])[0]), out); + const _114: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceAt(s, 0), 40)); + const _121: Uint8Array[] = [copy$array_u8(make$conversions_Value_array40_u8(data, 26))]; + const pointer2 = rs.cellArray(_114, rs.arraySliceOf(rs.byteSliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _121); + put$conversions_Value_array40_u8(rs.byteSliceFrom(old7[0]), out); rs.idx(s, 0); put$conversions_Value_array40_u8(rs.byteSliceFrom(replaceFirst$array40_u8(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 40), 1), [make$conversions_Value_array40_u8(data, 27)])[0]), out); rs.idx(s, 0); - put$conversions_Value_array40_u8(rs.byteSliceFrom(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 40), 1)), [[copy$array_u8(make$conversions_Value_array40_u8(data, 28))]])[0][0]), out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.arraySliceOne(rs.arraySliceAt(s, 0), 40), 1)); + const _148: Uint8Array[][] = [[copy$array_u8(make$conversions_Value_array40_u8(data, 28))]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.arraySliceOf(rs.byteSliceFrom))); + const old8 = rs.arraySliceCopy(pointer3); + rs.arraySliceSet(pointer3, _148); + put$conversions_Value_array40_u8(rs.byteSliceFrom(old8[0][0]), out); rs.idx(s, 0); const _159: rs.ByteSlice = rs.byteSliceFrom(other); const slice7 = rs.arraySliceAt(s, 0); @@ -1421,7 +1481,7 @@ export function lentParam$conversions_Logged(to: Logged.Logged, data: rs.ByteSli const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: Logged.Logged[] = [Logged.make$conversions_Value(data, 22)]; - const _76: Logged.Logged[] = rs.replaceIn(rs.sliceView(a), _77, 1); + const _76: Logged.Logged[] = rs.sliceReplaceAll(a, _77, 1); Logged.put$conversions_Value(_76[0], out); rs.dropAll(_76); const by: Logged.Logged = Logged.make$conversions_Value(data, 23); @@ -1429,7 +1489,7 @@ export function lentParam$conversions_Logged(to: Logged.Logged, data: rs.ByteSli let r: Logged.Logged = s.data[s.start]; const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); const _91: Logged.Logged[] = [by]; - const _88: Logged.Logged[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: Logged.Logged[] = rs.sliceReplaceAll(_89, _91); const _93: Logged.Logged = Logged.make$conversions_Value(data, 24); _88[0][Symbol.dispose](); Object.assign(_88[0], _93); @@ -1448,10 +1508,10 @@ export function lentParam$conversions_Logged(to: Logged.Logged, data: rs.ByteSli rs.idx(s, 0); const borrowed3 = s.data; const borrowed4 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))); const _121: Logged.Logged[] = [Logged.make$conversions_Value(data, 26)]; - const pointer2 = rs.sliceFrom(_114.v); - const old7 = rs.objectCopy(rs.sliceView(pointer2), 1); + const pointer2 = rs.cellArray(_114, rs.sliceFrom); + const old7 = rs.sliceCopy(pointer2, 1); rs.sliceSet(pointer2, _121); const old: Logged.Logged = old7[0]; Logged.put$conversions_Value(old, out); @@ -1463,7 +1523,12 @@ export function lentParam$conversions_Logged(to: Logged.Logged, data: rs.ByteSli rs.idx(s, 0); const borrowed7 = s.data; const borrowed8 = s.start; - const old3: Logged.Logged = rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), copy$conversions_Logged), [[Logged.make$conversions_Value(data, 28)]])[0][0]; + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), copy$conversions_Logged); + const _148: Logged.Logged[][] = [[Logged.make$conversions_Value(data, 28)]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old8 = rs.arraySliceCopy(pointer3, copy$conversions_Logged); + rs.arraySliceSet(pointer3, _148); + const old3: Logged.Logged = old8[0][0]; Logged.put$conversions_Value(old3, out); rs.idx(s, 0); rs.sliceReplace(s.data, s.start, Logged.clone$Clone(other))[Symbol.dispose](); @@ -1509,13 +1574,13 @@ export function lentParam$conversions_Named(to: Named.Named, data: rs.ByteSlice, const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: Named.Named[] = [Named.make$conversions_Value(data, 22)]; - Named.put$conversions_Value(rs.replaceIn(rs.sliceView(a), _77, 1)[0], out); + Named.put$conversions_Value(rs.sliceReplaceAll(a, _77, 1)[0], out); const by: Named.Named = Named.make$conversions_Value(data, 23); rs.idx(s, 0); let r: Named.Named = s.data[s.start]; const _89: rs.Slice = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); const _91: Named.Named[] = [by]; - Object.assign(rs.replaceIn(rs.sliceView(_89), _91)[0], Named.make$conversions_Value(data, 24)); + Object.assign(rs.sliceReplaceAll(_89, _91)[0], Named.make$conversions_Value(data, 24)); Named.put$conversions_Value(r, out); rs.idx(s, 0); Named.put$conversions_Value(s.data[s.start], out); @@ -1529,10 +1594,10 @@ export function lentParam$conversions_Named(to: Named.Named, data: rs.ByteSlice, rs.idx(s, 0); const borrowed3 = s.data; const borrowed4 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed3[borrowed4], (value3) => borrowed3[borrowed4] = value3))); const _121: Named.Named[] = [Named.make$conversions_Value(data, 26)]; - const pointer2 = rs.sliceFrom(_114.v); - const old7 = rs.objectCopy(rs.sliceView(pointer2), 1); + const pointer2 = rs.cellArray(_114, rs.sliceFrom); + const old7 = rs.sliceCopy(pointer2, 1); rs.sliceSet(pointer2, _121); Named.put$conversions_Value(old7[0], out); rs.idx(s, 0); @@ -1542,7 +1607,12 @@ export function lentParam$conversions_Named(to: Named.Named, data: rs.ByteSlice, rs.idx(s, 0); const borrowed7 = s.data; const borrowed8 = s.start; - Named.put$conversions_Value(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), copy$conversions_Named), [[Named.make$conversions_Value(data, 28)]])[0][0], out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed7[borrowed8], (value5) => borrowed7[borrowed8] = value5)), 1), copy$conversions_Named); + const _148: Named.Named[][] = [[Named.make$conversions_Value(data, 28)]]; + const pointer3 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old8 = rs.arraySliceCopy(pointer3, copy$conversions_Named); + rs.arraySliceSet(pointer3, _148); + Named.put$conversions_Value(old8[0][0], out); rs.idx(s, 0); s.data[s.start] = Named.clone$Clone(other); rs.idx(s, 0); @@ -1589,14 +1659,14 @@ export function lentParam$u32(to: rs.Place, data: rs.ByteSlice, out: rs. const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: rs.u32[] = [make$conversions_Value_u32(data, 22)]; - put$conversions_Value_u32(rs.replaceIn(rs.sliceView(a), _77)[0], out); + put$conversions_Value_u32(rs.sliceReplaceAll(a, _77)[0], out); let by: rs.u32 = make$conversions_Value_u32(data, 23); rs.idx(s, 0); const borrowed3 = s.start; let r: rs.Place = rs.place(() => s.data[borrowed3], (value2) => s.data[borrowed3] = value2); const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value3) => r = value3)); const _91: rs.Place[] = [rs.place(() => by, (value4) => by = value4)]; - rs.replaceIn(rs.sliceView(_89), _91)[0].v = make$conversions_Value_u32(data, 24); + rs.sliceReplaceAll(_89, _91)[0].v = make$conversions_Value_u32(data, 24); put$conversions_Value_u32(r.v, out); rs.idx(s, 0); put$conversions_Value_u32(s.data[s.start], out); @@ -1607,10 +1677,10 @@ export function lentParam$u32(to: rs.Place, data: rs.ByteSlice, out: rs. rs.idx(s, 0); const borrowed6 = s.data; const borrowed7 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))); const _121: rs.u32[] = [make$conversions_Value_u32(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer); rs.sliceSet(pointer, _121); put$conversions_Value_u32(old6[0], out); rs.idx(s, 0); @@ -1620,7 +1690,12 @@ export function lentParam$u32(to: rs.Place, data: rs.ByteSlice, out: rs. rs.idx(s, 0); const borrowed10 = s.data; const borrowed11 = s.start; - put$conversions_Value_u32(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)), [[make$conversions_Value_u32(data, 28)]])[0][0], out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)); + const _148: rs.u32[][] = [[make$conversions_Value_u32(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_u32(old7[0][0], out); rs.idx(s, 0); s.data[s.start] = other; rs.idx(s, 0); @@ -1667,14 +1742,14 @@ export function lentParam$u64(to: rs.Place, data: rs.ByteSlice, out: rs. const borrowed2 = s.start; const a: rs.Slice = rs.sliceOfPlace(rs.place(() => borrowed[borrowed2], (value) => borrowed[borrowed2] = value)); const _77: rs.u64[] = [make$conversions_Value_u64(data, 22)]; - put$conversions_Value_u64(rs.replaceIn(rs.sliceView(a), _77)[0], out); + put$conversions_Value_u64(rs.sliceReplaceAll(a, _77)[0], out); let by: rs.u64 = make$conversions_Value_u64(data, 23); rs.idx(s, 0); const borrowed3 = s.start; let r: rs.Place = rs.place(() => s.data[borrowed3], (value2) => s.data[borrowed3] = value2); const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value3) => r = value3)); const _91: rs.Place[] = [rs.place(() => by, (value4) => by = value4)]; - rs.replaceIn(rs.sliceView(_89), _91)[0].v = make$conversions_Value_u64(data, 24); + rs.sliceReplaceAll(_89, _91)[0].v = make$conversions_Value_u64(data, 24); put$conversions_Value_u64(r.v, out); rs.idx(s, 0); put$conversions_Value_u64(s.data[s.start], out); @@ -1685,10 +1760,10 @@ export function lentParam$u64(to: rs.Place, data: rs.ByteSlice, out: rs. rs.idx(s, 0); const borrowed6 = s.data; const borrowed7 = s.start; - const _114: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))))); + const _114: rs.Cell = rs.cellOfSlice(rs.sliceOfPlace(rs.place(() => borrowed6[borrowed7], (value6) => borrowed6[borrowed7] = value6))); const _121: rs.u64[] = [make$conversions_Value_u64(data, 26)]; - const pointer = rs.sliceFrom(_114.v); - const old6 = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(_114, rs.sliceFrom); + const old6 = rs.sliceCopy(pointer); rs.sliceSet(pointer, _121); put$conversions_Value_u64(old6[0], out); rs.idx(s, 0); @@ -1698,7 +1773,12 @@ export function lentParam$u64(to: rs.Place, data: rs.ByteSlice, out: rs. rs.idx(s, 0); const borrowed10 = s.data; const borrowed11 = s.start; - put$conversions_Value_u64(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)), [[make$conversions_Value_u64(data, 28)]])[0][0], out); + const _147: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => borrowed10[borrowed11], (value8) => borrowed10[borrowed11] = value8)), 1)); + const _148: rs.u64[][] = [[make$conversions_Value_u64(data, 28)]]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _148); + put$conversions_Value_u64(old7[0][0], out); rs.idx(s, 0); s.data[s.start] = other; rs.idx(s, 0); @@ -1762,8 +1842,7 @@ export function lentParam$u8(to: rs.Place, data: rs.ByteSlice, out: rs.By let r: rs.Place = rs.place(() => s.data[borrowed], (value) => s.data[borrowed] = value); const _89: rs.Slice> = rs.sliceOfPlace(rs.place(() => r, (value2) => r = value2)); rs.byteMirrorFlush(mirror); - const _91: rs.Place[] = [rs.place(() => by, (value3) => by = value3)]; - const _88: rs.Place[] = rs.replaceIn(rs.sliceView(_89), _91); + const _88: rs.Place[] = rs.sliceReplaceAll(_89, [rs.place(() => by, (value3) => by = value3)]); rs.byteMirrorFlush(mirror); const _93: rs.u8 = make$conversions_Value_u8(data, 24); rs.byteMirrorFlush(mirror); @@ -1809,7 +1888,11 @@ export function lentParam$u8(to: rs.Place, data: rs.ByteSlice, out: rs.By rs.byteMirrorFlush(mirror); const _147: rs.Cell = rs.cellOfArraySlice(b); rs.byteMirrorFlush(mirror); - const _146: Uint8Array[] = rs.cellReplace(_147, [Uint8Array.of(make$conversions_Value_u8(data, 28))]); + const _148: Uint8Array[] = [Uint8Array.of(make$conversions_Value_u8(data, 28))]; + const pointer2 = rs.cellArray(_147, rs.arraySliceOf(rs.byteSliceFrom)); + const old7 = rs.arraySliceCopy(pointer2); + rs.arraySliceSet(pointer2, _148); + const _146: Uint8Array[] = old7; rs.byteMirrorFlush(mirror); put$conversions_Value_u8(_146[0][0], out); rs.idx(s, 0); @@ -2202,8 +2285,8 @@ export function setThrough$array1_u8(to: rs.ByteSlice, value: Uint8Array): Uint8 /** A cell of what a `&mut` whose place only the caller knows points at, written through. */ export function setThrough$array2_u32(to: rs.Slice, value: rs.u32[]): rs.u32[] { - const pointer = rs.sliceFrom(rs.cellOfPlace(rs.partPlace(rs.sliceView(to))).v); - const old = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(rs.cellOfSlice(to), rs.sliceFrom); + const old = rs.sliceCopy(pointer); rs.sliceSet(pointer, copy$array_u32(value)); return old; } @@ -2841,29 +2924,23 @@ export function converted$array2_u32(data: rs.ByteSlice, out: rs.ByteVec): void const a: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 0)); const b: rs.u32[] = make$conversions_Value_array2_u32(data, 3); const owned: rs.u32[] = a.slice(); - const _8: rs.Slice = rs.sliceFrom(a); - const _9: rs.Slice = rs.sliceFrom(b); - rs.replaceIn(rs.sliceView(_8), rs.sliceToArray(_9)); + rs.sliceReplaceAll(rs.sliceFrom(a), b.slice()); put$conversions_Value_array2_u32(rs.sliceFrom(owned), out); put$conversions_Value_array2_u32(rs.sliceFrom(a), out); const c: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 6)); const _16: rs.Slice = rs.sliceFrom(owned); - rs.replaceIn(rs.sliceView(rs.sliceFrom(c)), rs.sliceToArray(_16)); + rs.sliceReplaceAll(rs.sliceFrom(c), rs.sliceToArray(_16)); put$conversions_Value_array2_u32(rs.sliceFrom(c), out); cloneFromParam$array2_u32(rs.sliceFrom(c), rs.sliceFrom(b)); cloneIntoParam$array2_u32(rs.sliceFrom(owned), rs.sliceFrom(a)); put$conversions_Value_array2_u32(rs.sliceFrom(c), out); put$conversions_Value_array2_u32(rs.sliceFrom(a), out); const held: Held.Held = new Held.Held(copy$array_u32(make$conversions_Value_array2_u32(data, 1))); - const _33: rs.Slice = rs.sliceFrom(held.value); - const _34: rs.Slice = rs.sliceFrom(c); - rs.replaceIn(rs.sliceView(_33), rs.sliceToArray(_34)); + rs.sliceReplaceAll(rs.sliceFrom(held.value), c.slice()); const v: rs.Vec = rs.vecFrom(copy$array_array2_u32([make$conversions_Value_array2_u32(data, 2), make$conversions_Value_array2_u32(data, 4)]).map(copy$array_u32)); - const _40: rs.Slice = rs.sliceFrom(v.items[rs.idx(v.items, 1)]); - const _42: rs.Slice = rs.sliceFrom(held.value); - rs.replaceIn(rs.sliceView(_40), rs.sliceToArray(_42)); + rs.sliceReplaceAll(rs.sliceFrom(v.items[rs.idx(v.items, 1)]), held.value.slice()); const _44: rs.Slice = rs.sliceFrom(b); - rs.replaceIn(rs.sliceView(rs.sliceFrom(v.items[rs.idx(v.items, 0)])), rs.sliceToArray(_44)); + rs.sliceReplaceAll(rs.sliceFrom(v.items[rs.idx(v.items, 0)]), rs.sliceToArray(_44)); put$conversions_Value_array2_u32(rs.sliceFrom(held.value), out); put$conversions_Value_array2_u32(rs.sliceFrom(v.items[rs.idx(v.items, 0)]), out); put$conversions_Value_array2_u32(rs.sliceFrom(v.items[rs.idx(v.items, 1)]), out); @@ -2871,26 +2948,24 @@ export function converted$array2_u32(data: rs.ByteSlice, out: rs.ByteVec): void rs.byteVecPush(out, one.length & 0xff); const copied: rs.u32[] = rs.sliceToArray(rs.arraySliceAt(one, 0)); put$conversions_Value_array2_u32(rs.arraySliceAt(one, 0), out); - const _70: rs.Slice = rs.sliceFrom(a); - const _71: rs.Slice = rs.sliceFrom(copied); - rs.replaceIn(rs.sliceView(_70), rs.sliceToArray(_71)); + rs.sliceReplaceAll(rs.sliceFrom(a), copied.slice()); put$conversions_Value_array2_u32(rs.sliceFrom(copied), out); put$conversions_Value_array2_u32(rs.sliceFrom(a), out); - const cell: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceFrom(c)))); + const cell: rs.Cell = rs.cellOfSlice(rs.sliceFrom(c)); const _79: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 10)); - const pointer = rs.sliceFrom(cell.v); - const old2 = rs.objectCopy(rs.sliceView(pointer)); + const pointer = rs.cellArray(cell, rs.sliceFrom); + const old2 = rs.sliceCopy(pointer); rs.sliceSet(pointer, _79); const old: rs.u32[] = old2; const _81: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 11)); - rs.sliceSet(rs.sliceFrom(cell.v), _81); + rs.sliceSet(rs.cellArray(cell, rs.sliceFrom), _81); put$conversions_Value_array2_u32(rs.sliceFrom(old), out); put$conversions_Value_array2_u32(rs.sliceFrom(c), out); put$conversions_Value_array2_u32(rs.sliceFrom(setThrough$array2_u32(rs.sliceFrom(v.items[rs.idx(v.items, 0)]), make$conversions_Value_array2_u32(data, 12))), out); put$conversions_Value_array2_u32(rs.sliceFrom(v.items[rs.idx(v.items, 0)]), out); - const _96: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.sliceView(rs.sliceFrom(held.value)))); + const _96: rs.Cell = rs.cellOfSlice(rs.sliceFrom(held.value)); const _98: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 17)); - rs.sliceSet(rs.sliceFrom(_96.v), _98); + rs.sliceSet(rs.cellArray(_96, rs.sliceFrom), _98); put$conversions_Value_array2_u32(rs.sliceFrom(held.value), out); const array: rs.u32[][] = [copy$array_u32(make$conversions_Value_array2_u32(data, 13)), copy$array_u32(make$conversions_Value_array2_u32(data, 14)), copy$array_u32(make$conversions_Value_array2_u32(data, 15))]; rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([rs.arraySliceFrom(array, rs.sliceFrom).length, rs.arraySliceFrom(array, rs.sliceFrom).length], (n: rs.usize): rs.u8 => { @@ -2903,7 +2978,7 @@ export function converted$array2_u32(data: rs.ByteSlice, out: rs.ByteVec): void const _124: rs.ArraySlice> = rs.arraySliceFrom(array, rs.sliceFrom); rs.idx(_124, 2); const _130: rs.Slice = rs.sliceFrom(c); - rs.replaceIn(rs.sliceView(rs.arraySliceAt(_124, 2)), rs.sliceToArray(_130)); + rs.sliceReplaceAll(rs.arraySliceAt(_124, 2), rs.sliceToArray(_130)); const iter: rs.Iter> = rs.arraySliceIter(rs.arraySliceFrom(array, rs.sliceFrom)); while (true) { const _134: rs.Slice | rs.Done = iter.next(); @@ -2924,7 +2999,7 @@ export function converted$array2_u32(data: rs.ByteSlice, out: rs.ByteVec): void const _173: rs.ArraySlice> = rs.arraySliceFrom(list.items, rs.sliceFrom); rs.idx(_173, 1); const _179: rs.Slice = rs.sliceFrom(c); - rs.replaceIn(rs.sliceView(rs.arraySliceAt(_173, 1)), rs.sliceToArray(_179)); + rs.sliceReplaceAll(rs.arraySliceAt(_173, 1), rs.sliceToArray(_179)); rs.arraySliceSwap(rs.arraySliceFrom(list.items, rs.sliceFrom), 0, 1, undefined); const _184: rs.Vec = list; const _186: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 15)); @@ -4742,7 +4817,7 @@ export function lentOne$array2_u32(data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteVecPush(out, s.length & 0xff); rs.idx(s, 0); const _28: rs.u32[] = copy$array_u32(make$conversions_Value_array2_u32(data, 5)); - put$conversions_Value_array2_u32(rs.sliceFrom(rs.replaceIn(rs.sliceView(rs.arraySliceAt(s, 0)), _28)), out); + put$conversions_Value_array2_u32(rs.sliceFrom(rs.sliceReplaceAll(rs.arraySliceAt(s, 0), _28)), out); put$conversions_Value_array2_u32(rs.sliceFrom(a), out); put$conversions_Value_array2_u32(rs.sliceFrom(writeFirst$array2_u32(rs.arraySliceOne(rs.sliceFrom(held.value), 2), make$conversions_Value_array2_u32(data, 7))), out); put$conversions_Value_array2_u32(rs.sliceFrom(held.value), out); diff --git a/ts/fixtures/lang/objects/expected/objects.ts b/ts/fixtures/lang/objects/expected/objects.ts index 9dfda98b8..ebf3f5492 100644 --- a/ts/fixtures/lang/objects/expected/objects.ts +++ b/ts/fixtures/lang/objects/expected/objects.ts @@ -142,8 +142,7 @@ export function swapIn(v: rs.Vec>, with_: rs.Arc): rs.Vec, to: rs.u16): rs.u16[] { const captured = to; return ((): rs.u16[] => { - const _2: rs.u16[] = [captured, rs.u16WrappingAdd(captured, 1)]; - return rs.replaceIn(rs.sliceView(a), _2); + return rs.sliceReplaceAll(a, [captured, rs.u16WrappingAdd(captured, 1)]); })(); } diff --git a/ts/fixtures/lang/pointers/expected/core/option.ts b/ts/fixtures/lang/pointers/expected/core/option.ts index 8f6edbacb..13623916b 100644 --- a/ts/fixtures/lang/pointers/expected/core/option.ts +++ b/ts/fixtures/lang/pointers/expected/core/option.ts @@ -69,6 +69,20 @@ export function mapOr$00zno7m(self: Spot.Spot | undefined, default_: Spot.Spot, return f(copy$pointers_Spot(self)); } +export function mapOr$0m14xib(self: Uint8Array | rs.None, default_: Uint8Array, f: (a0: Uint8Array) => Uint8Array): Uint8Array { + if (self === rs.None) { + return default_; + } + return f(self); +} + +export function mapOr$1wlsr3s(self: rs.u8 | undefined, default_: rs.u32, f: (a0: rs.u8) => rs.u32): rs.u32 { + if (self === undefined) { + return default_; + } + return f(self); +} + export function mapOr$173j2gr(self: [rs.u8, rs.Arc] | undefined, default_: rs.u8, f: (a0: [rs.u8, rs.Arc]) => rs.u8): rs.u8 { if (self === undefined) { return default_; diff --git a/ts/fixtures/lang/pointers/expected/lib.ts b/ts/fixtures/lang/pointers/expected/lib.ts index d654e3dda..9de202b84 100644 --- a/ts/fixtures/lang/pointers/expected/lib.ts +++ b/ts/fixtures/lang/pointers/expected/lib.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { lists, shared, places, unchecked, nested, copies, sentinels, cells, rebound, lapsed, writers, made, segments, uninitRuns, iteratedRuns, besideWritten, waiters, taken, bytes, loaded, reattached, partWritten, aimed, distinct, rawArcs, rawPlaces, arrays, arrayCasts, genericUnions, rawCells, cellWrites, nestedCells, loneBytes } from "./pointers.ts"; +import { lists, shared, places, unchecked, nested, copies, sentinels, cells, rebound, lapsed, writers, made, segments, uninitRuns, iteratedRuns, besideWritten, waiters, taken, bytes, loaded, reattached, partWritten, aimed, distinct, rawArcs, rawPlaces, arrays, arrayCasts, genericUnions, rawCells, cellWrites, nestedCells, loneBytes, arrayParts } from "./pointers.ts"; import type * as Aimed from "./pointers.Aimed.ts"; import * as Bin from "./pointers.Bin.ts"; import type * as ByCall from "./pointers.ByCall.ts"; @@ -323,6 +323,8 @@ export function cases(): rs.Vec<[string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.By nestedCells(data32, out32); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::lone_bytes", (_242: rs.u8, data33: rs.ByteSlice, out33: rs.ByteVec): undefined => { loneBytes(data33, out33); + }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["pointers::array_parts", (_243: rs.u8, data34: rs.ByteSlice, out34: rs.ByteVec): undefined => { + arrayParts(data34, out34); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]]); } diff --git a/ts/fixtures/lang/pointers/expected/pointers.ts b/ts/fixtures/lang/pointers/expected/pointers.ts index 5e9b3d68b..748742a41 100644 --- a/ts/fixtures/lang/pointers/expected/pointers.ts +++ b/ts/fixtures/lang/pointers/expected/pointers.ts @@ -3,7 +3,7 @@ import * as rs from "./rs.ts"; import { copy$Option_pointers_Pair, copy$Option_tuple2_u16_u8, copy$array_array2_u32, copy$array_ptr_array4_u8, copy$array_tuple2_u8_u8, copy$array_u16, copy$array_u32, copy$array_u8, copy$mem_MaybeUninit_array_u32, copy$mem_MaybeUninit_array_u8, copy$mem_MaybeUninit_tuple2_u8_u8, copy$pointers_Aimed_Cell_u8, copy$pointers_Aimed_array2_u16, copy$pointers_Aimed_array4_u8, copy$pointers_Aimed_pointers_Housed_u8, copy$pointers_Aimed_pointers_Leaning, copy$pointers_Aimed_pointers_Paired, copy$pointers_Aimed_u8, copy$pointers_ByCall, copy$pointers_ByClosure, copy$pointers_ByObject, copy$pointers_Duo, copy$pointers_Either_u32, copy$pointers_Either_u8, copy$pointers_Halves, copy$pointers_Outer, copy$pointers_Pair, copy$pointers_Reentrant, copy$pointers_Spot, copy$pointers_Twin, copy$tuple2_array2_u32_u8, copy$tuple2_u16_u8, copy$tuple2_u32_u32, copy$tuple2_u8_u16, copy$tuple2_u8_u8, drop$pointers_List_String, drop$pointers_List_sync_Arc_u8, drop$tuple2_sync_Arc_pointers_Twin_Rc_pointers_Twin, drop$tuple3_sync_Arc_u32_Rc_pointers_Duo_sync_Arc_unit, drop$tuple4_sync_Arc_pointers_Twin_sync_Arc_pointers_Twin_Rc_pointers_Twin_Rc_pointers_Twin, of$pointers_Bin_pointers_ByObject } from "./lib.ts"; import { then$0bgt67i, then$1a5xgoh, then$0jw3xip } from "./core/bool.ts"; -import { isSomeAnd$1s2u5lz, isSomeAnd$1nosv3e, isSomeAnd$07atiew, unwrapOr$0mkoact as option_unwrapOr$0mkoact, unwrapOr$179xo1w as option_unwrapOr$179xo1w, unwrapOr$1fr498u as option_unwrapOr$1fr498u, map$1cfrse5 as option_map$1cfrse5, mapOr$078vnqn as option_mapOr$078vnqn, mapOr$00zno7m as option_mapOr$00zno7m, mapOr$173j2gr as option_mapOr$173j2gr, filter$0wvwd70 } from "./core/option.ts"; +import { isSomeAnd$1s2u5lz, isSomeAnd$1nosv3e, isSomeAnd$07atiew, unwrapOr$0mkoact as option_unwrapOr$0mkoact, unwrapOr$179xo1w as option_unwrapOr$179xo1w, unwrapOr$1fr498u as option_unwrapOr$1fr498u, map$1cfrse5 as option_map$1cfrse5, mapOr$078vnqn as option_mapOr$078vnqn, mapOr$00zno7m as option_mapOr$00zno7m, mapOr$0m14xib as option_mapOr$0m14xib, mapOr$1wlsr3s as option_mapOr$1wlsr3s, mapOr$173j2gr as option_mapOr$173j2gr, filter$0wvwd70 } from "./core/option.ts"; import type * as Aimed from "./pointers.Aimed.ts"; import * as Bin from "./pointers.Bin.ts"; import type * as ByCall from "./pointers.ByCall.ts"; @@ -1260,12 +1260,12 @@ export function wrapped(n: rs.u8): Uint8Array { const nonNull: rs.ByteSlice = rs.byteSliceFrom(a); const shared: rs.ByteSlice = rs.byteSliceFrom(a); const same: boolean = rs.byteSliceSame(nonNull, shared); - const _10: rs.ByteSlice = rs.byteSliceFrom(rs.byteSliceView(nonNull)); + const _10: rs.ByteSlice = nonNull; _10.data[_10.start + 1] = n ^ 85; - const _15: rs.ByteSlice = rs.byteSliceFrom(rs.byteSliceView(shared)); + const _15: rs.ByteSlice = shared; const viewed: rs.u8 = _15.data[_15.start + 1]; const pointer = nonNull; - const _20: rs.ByteSlice = rs.optionUnwrap(rs.optionMap(pointer === rs.NULL ? undefined : rs.byteSliceView(pointer), rs.byteSliceFrom)); + const _20: rs.ByteSlice = rs.optionUnwrap(pointer === rs.NULL ? undefined : pointer); const asRef: rs.u8 = _20.data[_20.start]; const boxed: rs.ByteSlice = rs.byteSliceFrom(rs.bytes(3).fill(n)); boxed.data[boxed.start + 2] = 9; @@ -3008,7 +3008,7 @@ export function arrayCasts(data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteVecPush(out, rs.byteSliceSame(pair, rs.optionUnwrap(rs.byteSliceGetRange(rest, 0, 2))) ? 1 : 0); rs.byteVecPush(out, rs.byteSliceSame(pair, rs.optionUnwrap(rs.byteSliceGetRange(rest, 0, 2))) ? 1 : 0); } - const _43: rs.ByteSlice = rs.byteSliceFrom(rs.byteSliceView(rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), at)).byteArray(1))); + const _43: rs.ByteSlice = rs.rawByteSliceOf(rs.byteSliceRange(rs.byteVecSlice(bytes), at)).byteArray(1); rs.byteVecPush(out, _43.data[_43.start]); } if (bytes.length >= 3) { @@ -3190,7 +3190,7 @@ export function rawCells(data: rs.ByteSlice, out: rs.ByteVec): void { } _67.data[_67.start + _70] = _67.data[_67.start + _70] ^ n; const _74: rs.u16 = ((n as rs.u16) << 4) & 0xffff; - const _78: rs.Slice = rs.sliceFrom(wide.v); + const _78: rs.Slice = rs.cellArray(wide, rs.sliceFrom); const _81: rs.usize = rs.u8Rem(n, 2) as rs.usize; if (!(_81 < 2)) { rs.panic("index out of bounds: the len is " + 2 + " but the index is " + _81); @@ -3200,7 +3200,7 @@ export function rawCells(data: rs.ByteSlice, out: rs.ByteVec): void { rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(duo.v._1, held.v.n)), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(pair.v[1]).reverse()), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(rs.byteSliceToArray(rs.byteSliceFrom(bytes.v))), undefined, true); - const _110: rs.Slice = rs.sliceFrom(wide.v); + const _110: rs.Slice = rs.cellArray(wide, rs.sliceFrom); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(_110.data[_110.start + 1]).reverse()), undefined, true); } else if (_41 === 1) { const p: rs.Place> = rs.place(() => num, (value9) => num = value9); @@ -3315,12 +3315,12 @@ export function rawCells(data: rs.ByteSlice, out: rs.ByteVec): void { _303[1] = _303[1] ^ _302; const _305: rs.ByteSlice = rs.byteSliceFrom(bytes.v); _305.data[_305.start + 1] = _305.data[_305.start + 1] ^ n; - rs.sliceSet(rs.sliceFrom(wide.v), [n as rs.u16, 1]); + rs.sliceSet(rs.cellArray(wide, rs.sliceFrom), [n as rs.u16, 1]); rs.iterExtendBytes(out, rs.iterSlice(rs.u32ToBeBytes(num.v).reverse()), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(held.v.n, duo.v._0)), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(pair.v[1]).reverse()), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(rs.byteSliceView(rs.byteSliceFrom(bytes.v))), undefined, true); - const _336: rs.Slice = rs.sliceFrom(wide.v); + const _336: rs.Slice = rs.cellArray(wide, rs.sliceFrom); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(_336.data[_336.start]).reverse()), undefined, true); const arr: Uint8Array = Uint8Array.of(n, 1, 2); const a: rs.Cell = rs.cellOfPlace(rs.partPlace(rs.byteSliceView(rs.byteSliceFrom(arr)))); @@ -3457,7 +3457,7 @@ export function cellWrites(data: rs.ByteSlice, out: rs.ByteVec): void { const toPair: [rs.u8, rs.u16] = _21[0]; const toDuo: Duo.Duo = _21[1]; const toOwner: Held.Held = _21[2]; - const _30: [rs.ByteSlice, rs.Slice] = [rs.byteSliceFrom(bytes.v), rs.sliceFrom(wide.v)]; + const _30: [rs.ByteSlice, rs.Slice] = [rs.byteSliceFrom(bytes.v), rs.cellArray(wide, rs.sliceFrom)]; const toBytes: rs.ByteSlice = _30[0]; const toWide: rs.Slice = _30[1]; const lent: [rs.u8, rs.u16] = [10, 11]; @@ -3489,8 +3489,8 @@ export function cellWrites(data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteSliceSet(pointer18, _72); rs.iterExtendBytes(out, rs.iterSlice(old19), undefined, true); const _78: rs.u16[] = [n as rs.u16, 2]; - const pointer19 = rs.sliceFrom(wide.v); - const old20 = rs.objectCopy(rs.sliceView(pointer19)); + const pointer19 = rs.cellArray(wide, rs.sliceFrom); + const old20 = rs.sliceCopy(pointer19); rs.sliceSet(pointer19, _78); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(old20[1]).reverse()), undefined, true); } else if (_46 === 1) { @@ -3504,7 +3504,7 @@ export function cellWrites(data: rs.ByteSlice, out: rs.ByteVec): void { const _98: Uint8Array = Uint8Array.of(n ^ 4, 5); rs.byteSliceSet(rs.byteSliceFrom(bytes.v), _98); const _102: rs.u16[] = [6, ((n as rs.u16) << 4) & 0xffff]; - rs.sliceSet(rs.sliceFrom(wide.v), _102); + rs.sliceSet(rs.cellArray(wide, rs.sliceFrom), _102); } else if (_46 === 2) { const _110: rs.Cell<[rs.u8, rs.u16]> = new rs.Cell([n, 7] as [rs.u8, rs.u16]); const x2 = pair.v; @@ -3542,8 +3542,8 @@ export function cellWrites(data: rs.ByteSlice, out: rs.ByteVec): void { const value5 = Array.from({ length: 2 }, (): rs.u16 => { return 0; }); - const pointer13 = rs.sliceFrom(wide.v); - const old11 = rs.objectCopy(rs.sliceView(pointer13)); + const pointer13 = rs.cellArray(wide, rs.sliceFrom); + const old11 = rs.sliceCopy(pointer13); rs.sliceSet(pointer13, value5); rs.iterExtendBytes(out, rs.iterSlice(rs.u16ToBeBytes(old11[0]).reverse()), undefined, true); } else if (_46 === 4) { @@ -3568,7 +3568,7 @@ export function cellWrites(data: rs.ByteSlice, out: rs.ByteVec): void { const a6: rs.u16 = _29[0]; return [rs.intRotateLeft(_29[1], n as rs.u32, 16, false), a6]; }; - const pointer10 = rs.sliceFrom(wide.v); + const pointer10 = rs.cellArray(wide, rs.sliceFrom); rs.sliceSet(pointer10, _165(rs.sliceToArray(pointer10))); } else if (_46 === 6) { ((c3: rs.Cell): undefined => { @@ -4076,4 +4076,104 @@ export function tripled(b: rs.u8): rs.u8 { return b2[0]; } +/** + * A raw pointer to a `[T; N]` and to a `[[T; N]; M]` that is part of a slice, lent back as + * a reference by `as_mut` and `NonNull::as_mut`, and the first written whole by + * `ptr::replace` and `ptr::swap` and taken back as a box by `Box::from_raw`; and arrays a + * `MaybeUninit` holds, lent by `as_ref` of bytes and by a cell's `get_mut` and + * `as_mut_unchecked`. + */ +export function arrayParts(data: rs.ByteSlice, out: rs.ByteVec): void { + const n: rs.u32 = option_mapOr$1wlsr3s(rs.byteSliceFirst(data), 0, (_2: rs.u8): rs.u32 => { + return _2 as rs.u32; + }); + const words: rs.Vec = rs.iterToVec(rs.iterMap(rs.iterSlice(rs.byteSliceView(data)), (_22: rs.u8): rs.u32 => { + return _22 as rs.u32; + }), undefined, 4, true); + rs.vecResize(words, rs.max(words.items.length, 6), 9, 4, undefined); + const p: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 1), 0, 2)); + const pointer = p; + const _19: rs.Slice | undefined = pointer === rs.NULL ? undefined : pointer; + if (_19 !== undefined) { + _19.data[_19.start] = n; + } + const _25: rs.u32[] = [rs.u32Add(n, 1), rs.u32Add(n, 2)]; + const pointer2 = p; + const old2 = rs.sliceCopy(pointer2); + rs.sliceSet(pointer2, _25); + rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(old2), (_24: rs.u32): rs.u8 => { + return _24 & 0xff; + }), undefined, true); + const q: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 3), 0, 2)); + const x = rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 1), 0, 2)); + const y = q; + const old3 = rs.sliceCopy(x); + rs.sliceSet(x, rs.sliceCopy(y)); + rs.sliceSet(y, old3); + const nn: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 2), 0, 2)); + const _54: rs.u32 = rs.u32Add(n, 3); + const _55: rs.Slice = nn; + _55.data[_55.start + 1] = _54; + const raw: rs.Slice = rs.sliceFrom([n, rs.u32Add(n, 1), rs.u32Add(n, 2)]); + raw.data[raw.start + 1] = 7; + rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(rs.boxArrayFromRaw(raw)), (_210: rs.u32): rs.u8 => { + return _210 & 0xff; + }), undefined, true); + const raw2: rs.RawSlice = rs.rawSliceOf(rs.sliceFrom([undefined, undefined, undefined])); + const fewer: undefined[] = (new Array(2) as unknown) as undefined[]; + const more: undefined[] = (new Array(5) as unknown) as undefined[]; + const slice5 = rs.sliceFrom(words.items); + raw2.array(2); + raw2.array(5); + rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(slice5, 2), 0, 0)); + const none2: rs.u32[] = (new Array(0) as unknown) as rs.u32[]; + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([rs.sliceFrom(fewer).length, rs.iterCount(rs.iterSlice(more)), rs.sliceFrom(none2).length], (n2: rs.usize): rs.u8 => { + return n2 & 0xff; + })), undefined, true); + rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(words.items), (_211: rs.u32): rs.u8 => { + return _211 & 0xff; + }), undefined, true); + const rows: rs.Vec = rs.iterToVec(rs.iterMap(rs.sliceChunks(rs.sliceFrom(words.items), 2), (c: rs.Slice): rs.u32[] => { + rs.idx(c, 0); + const _3: rs.u32 = c.data[c.start]; + const _8: rs.usize = rs.usizeSub(c.length, 1); + rs.idx(c, _8); + return [_3, c.data[c.start + _8]]; + }), undefined, 8, true); + const p3: rs.ArraySlice> = rs.optionUnwrap(rs.arraySliceGetRange(rs.arraySliceRange(rs.arraySliceFrom(rows.items, rs.sliceFrom), 1), 0, 2)); + const pointer3 = p3; + const _117: rs.ArraySlice> | undefined = pointer3 === rs.NULL ? undefined : pointer3; + if (_117 !== undefined) { + const _120: rs.u32 = rs.u32Add(n, 4); + const slice7 = rs.arraySliceAt(_117, 1); + slice7.data[slice7.start] = _120; + } + const pointer4 = p3; + const nn2: rs.ArraySlice> = rs.optionUnwrap(pointer4 === rs.NULL ? undefined : pointer4); + const _127: rs.u32 = rs.u32Add(n, 5); + const slice8 = rs.arraySliceAt(nn2, 0); + slice8.data[slice8.start + 1] = _127; + rs.iterExtendBytes(out, rs.iterMap(rs.iterFlatten(rs.arraySliceIter(rs.arraySliceFrom(rows.items, rs.sliceFrom)), (value: rs.Slice) => rs.iterSlice(rs.sliceItems(value)), true, 2), (_212: rs.u32): rs.u8 => { + return _212 & 0xff; + }), undefined, true); + const pointer5 = rs.byteSliceFrom(Uint8Array.of(n & 0xff, 5)); + rs.iterExtendBytes(out, rs.iterSlice(option_mapOr$0m14xib(pointer5 === rs.NULL ? rs.None : rs.byteSliceView(pointer5), rs.bytes(2), (m: Uint8Array): Uint8Array => { + return copy$mem_MaybeUninit_array_u8(m); + })), undefined, true); + const cell: rs.Cell = new rs.Cell(copy$mem_MaybeUninit_array_u8(Uint8Array.of(n & 0xff, 2))); + const _153: rs.ByteSlice = rs.byteSliceFrom(cell.v); + _153.data[_153.start + 1] = 9; + rs.iterExtendBytes(out, rs.iterSlice(cell.v), undefined, true); + const uc: rs.Cell = new rs.Cell(copy$mem_MaybeUninit_array_u32([n, 3])); + const _165: rs.u32 = rs.u32Add(n, 8); + const _166: rs.Slice = rs.sliceFrom(uc.v); + _166.data[_166.start] = _165; + const _171: rs.u32 = rs.u32Add(n, 9); + const _172: rs.Slice = rs.sliceFrom(uc.v); + _172.data[_172.start + 1] = _171; + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap(uc.v, (w5: rs.u32): rs.u8 => { + return w5 & 0xff; + })), undefined, true); +} + //# sourceMappingURL=pointers.ts.map diff --git a/ts/fixtures/lang/pointers/src/lib.rs b/ts/fixtures/lang/pointers/src/lib.rs index 985c039c8..52f681baf 100644 --- a/ts/fixtures/lang/pointers/src/lib.rs +++ b/ts/fixtures/lang/pointers/src/lib.rs @@ -59,6 +59,7 @@ fn cases() -> Vec<(&'static str, Case)> { pointers::nested_cells(data, out) }), ("pointers::lone_bytes", |_, data, out| pointers::lone_bytes(data, out)), + ("pointers::array_parts", |_, data, out| pointers::array_parts(data, out)), ] } diff --git a/ts/fixtures/lang/pointers/src/pointers.rs b/ts/fixtures/lang/pointers/src/pointers.rs index 1705c9f96..56d259cd0 100644 --- a/ts/fixtures/lang/pointers/src/pointers.rs +++ b/ts/fixtures/lang/pointers/src/pointers.rs @@ -5,7 +5,7 @@ //! `UnsafeCell::get` gives; slots of fresh memory written whole before any pointer //! into them is taken, by index or through std's iterators over them; pointers into //! nodes that an `AtomicPtr` and memory hold pointers to; pointers to arrays, compared -//! where they point; a +//! where they point, and to parts of slices as arrays, written through; a //! pointer into a cell that other functions write whole through a `&mut` to it; //! pointers a generic type holds to its parameter, at each form a pointer takes; the //! raw pointers of an `Arc` and an `Rc`, counted and taken back; and unions over a type @@ -3034,3 +3034,60 @@ fn tripled(mut b: u8) -> u8 { s[0] = s[0].wrapping_mul(3); b } + +/// A raw pointer to a `[T; N]` and to a `[[T; N]; M]` that is part of a slice, lent back as +/// a reference by `as_mut` and `NonNull::as_mut`, and the first written whole by +/// `ptr::replace` and `ptr::swap` and taken back as a box by `Box::from_raw`; and arrays a +/// `MaybeUninit` holds, lent by `as_ref` of bytes and by a cell's `get_mut` and +/// `as_mut_unchecked`. +pub fn array_parts(data: &[u8], out: &mut Vec) { + let n = data.first().map_or(0, |&b| u32::from(b)); + let mut words: Vec = data.iter().map(|&b| u32::from(b)).collect(); + words.resize(words.len().max(6), 9); + let a: &mut [u32; 2] = words[1..].first_chunk_mut().unwrap(); + let p: *mut [u32; 2] = a; + if let Some(a) = unsafe { p.as_mut() } { + a[0] = n; + } + let old = unsafe { ptr::replace(p, [n + 1, n + 2]) }; + out.extend(old.iter().map(|&w| w as u8)); + let q: *mut [u32; 2] = words[3..].first_chunk_mut().unwrap(); + let p: *mut [u32; 2] = words[1..].first_chunk_mut().unwrap(); + unsafe { ptr::swap(p, q) }; + let mut nn = NonNull::from(words[2..].first_chunk_mut::<2>().unwrap()); + unsafe { nn.as_mut()[1] = n + 3 }; + let boxed = Box::new([n, n + 1, n + 2]); + let raw = Box::into_raw(boxed); + unsafe { (*raw)[1] = 7 }; + let back = unsafe { Box::from_raw(raw) }; + out.extend(back.iter().map(|&w| w as u8)); + // Of arrays of no bytes, whose box owns no allocation, so any pointer to one makes one. + let units: Box<[()]> = Box::new([(); 3]); + let raw = Box::into_raw(units); + let fewer = unsafe { Box::from_raw(raw as *mut [(); 2]) }; + let more = unsafe { Box::from_raw(raw as *mut [(); 5]) }; + let none: *mut [u32; 0] = words[2..].first_chunk_mut().unwrap(); + let none = unsafe { Box::from_raw(none) }; + out.extend([fewer.len(), more.iter().count(), none.len()].map(|n| n as u8)); + out.extend(words.iter().map(|&w| w as u8)); + // Of arrays of arrays. + let mut rows: Vec<[u32; 2]> = words.chunks(2).map(|c| [c[0], c[c.len() - 1]]).collect(); + let p: *mut [[u32; 2]; 2] = rows[1..].first_chunk_mut().unwrap(); + if let Some(r) = unsafe { p.as_mut() } { + r[1][0] = n + 4; + } + let mut nn = NonNull::new(p).unwrap(); + unsafe { nn.as_mut()[0][1] = n + 5 }; + out.extend(rows.iter().flatten().map(|&w| w as u8)); + // Of arrays a `MaybeUninit` holds, whose reference is the array. + let bytes = MaybeUninit::new([n as u8, 5]); + let p: *const MaybeUninit<[u8; 2]> = &bytes; + out.extend(unsafe { p.as_ref() }.map_or([0; 2], |m| unsafe { m.assume_init() })); + let mut cell = Cell::new(MaybeUninit::new([n as u8, 2])); + unsafe { cell.get_mut().assume_init_mut()[1] = 9 }; + out.extend(unsafe { cell.into_inner().assume_init() }); + let mut uc = UnsafeCell::new(MaybeUninit::new([n, 3])); + unsafe { uc.get_mut().assume_init_mut()[0] = n + 8 }; + unsafe { uc.as_mut_unchecked().assume_init_mut()[1] = n + 9 }; + out.extend(unsafe { uc.into_inner().assume_init() }.map(|w| w as u8)); +} diff --git a/ts/fixtures/lang/slices/expected/core/option.ts b/ts/fixtures/lang/slices/expected/core/option.ts index 544458dd4..152c7e08f 100644 --- a/ts/fixtures/lang/slices/expected/core/option.ts +++ b/ts/fixtures/lang/slices/expected/core/option.ts @@ -59,6 +59,14 @@ export function map$13tab2s(self: rs.u16[] | undefined, f: (a0: rs.u16[]) => rs. return f(copy$array_u16(self)); } +export function map$0cigbgc(self: rs.Slice | undefined, f: (a0: rs.Slice) => undefined): undefined | rs.None { + if (self === undefined) { + return rs.None; + } + f(self); + return undefined; +} + export function map$0duedp1(self: rs.Slice | undefined, f: (a0: rs.Slice) => rs.u8): rs.u8 | undefined { if (self === undefined) { return undefined; diff --git a/ts/fixtures/lang/slices/expected/lib.ts b/ts/fixtures/lang/slices/expected/lib.ts index 9eec864ab..e894c911a 100644 --- a/ts/fixtures/lang/slices/expected/lib.ts +++ b/ts/fixtures/lang/slices/expected/lib.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { parts, chunked, subslices, drains, ranges, edits, arrays, arraysMut, arrayForms, arrayIdentity, arraySources, itemWrites } from "./slices.ts"; +import { parts, chunked, subslices, drains, ranges, edits, arrays, arraysMut, arrayForms, arrayIdentity, arraySources, itemWrites, arrayParts } from "./slices.ts"; import type * as Noisy from "./slices.Noisy.ts"; import type * as Pair from "./slices.Pair.ts"; @@ -29,6 +29,10 @@ export function copy$array_u16(v: rs.u16[]): rs.u16[] { return v.slice(); } +export function copy$array_u32(v: rs.u32[]): rs.u32[] { + return v.slice(); +} + export function copy$array_u8(v: Uint8Array): Uint8Array { return v.slice(); } @@ -53,7 +57,7 @@ export function drop$tuple2_Vec_slices_Noisy_Vec_u8(_1: [rs.Vec, rs * their count, so a case added at the end moves no other. */ export function cases(): rs.Vec<[string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]> { - return rs.vecFrom([["slices::parts", parts as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::drains", drains as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::chunked", chunked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::subslices", subslices as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::ranges", ranges as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::edits", edits as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::arrays", arrays as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::arrays_mut", arraysMut as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_forms", arrayForms as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_identity", arrayIdentity as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_sources", arraySources as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::item_writes", itemWrites as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]]); + return rs.vecFrom([["slices::parts", parts as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::drains", drains as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::chunked", chunked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::subslices", subslices as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::ranges", ranges as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::edits", edits as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::arrays", arrays as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::arrays_mut", arraysMut as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_forms", arrayForms as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_identity", arrayIdentity as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_sources", arraySources as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::item_writes", itemWrites as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["slices::array_parts", arrayParts as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]]); } //# sourceMappingURL=lib.ts.map diff --git a/ts/fixtures/lang/slices/expected/slices.ts b/ts/fixtures/lang/slices/expected/slices.ts index d825f8d0a..ab1bb1ea1 100644 --- a/ts/fixtures/lang/slices/expected/slices.ts +++ b/ts/fixtures/lang/slices/expected/slices.ts @@ -1,9 +1,9 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { copy$Option_array2_u16, copy$Option_array2_u8, copy$array_array2_array2_u8, copy$array_array2_u16, copy$array_array2_u8, copy$array_u16, copy$array_u8, copy$mem_MaybeUninit_array_u8, copy$slices_Pair, drop$tuple2_Vec_slices_Noisy_Vec_u8 } from "./lib.ts"; +import { copy$Option_array2_u16, copy$Option_array2_u8, copy$array_array2_array2_u8, copy$array_array2_u16, copy$array_array2_u8, copy$array_u16, copy$array_u32, copy$array_u8, copy$mem_MaybeUninit_array_u8, copy$slices_Pair, drop$tuple2_Vec_slices_Noisy_Vec_u8 } from "./lib.ts"; import { thenSome$1gvhopg } from "./core/bool.ts"; -import { isSomeAnd$1ouf3e6, unwrapOr$1la41a6 as option_unwrapOr$1la41a6, unwrapOr$1fr498u as option_unwrapOr$1fr498u, unwrapOrDefault$1n9qa5p as option_unwrapOrDefault$1n9qa5p, unwrapOrDefault$0h81s8g as option_unwrapOrDefault$0h81s8g, map$13tab2s as option_map$13tab2s, map$0duedp1 as option_map$0duedp1, map$0q6fk7x as option_map$0q6fk7x, map$1uud0v7 as option_map$1uud0v7, map$1j0y4j0 as option_map$1j0y4j0, map$0vk4zok as option_map$0vk4zok, map$1aqm6sp as option_map$1aqm6sp, map$04ry0e1 as option_map$04ry0e1, mapOr$135q041 as option_mapOr$135q041, mapOr$17z0l8m as option_mapOr$17z0l8m, or$0as8tia as option_or$0as8tia, zip$0wdt346, clone$1omlcob as option_clone$1omlcob } from "./core/option.ts"; +import { isSomeAnd$1ouf3e6, unwrapOr$1la41a6 as option_unwrapOr$1la41a6, unwrapOr$1fr498u as option_unwrapOr$1fr498u, unwrapOrDefault$1n9qa5p as option_unwrapOrDefault$1n9qa5p, unwrapOrDefault$0h81s8g as option_unwrapOrDefault$0h81s8g, map$13tab2s as option_map$13tab2s, map$0cigbgc as option_map$0cigbgc, map$0duedp1 as option_map$0duedp1, map$0q6fk7x as option_map$0q6fk7x, map$1uud0v7 as option_map$1uud0v7, map$1j0y4j0 as option_map$1j0y4j0, map$0vk4zok as option_map$0vk4zok, map$1aqm6sp as option_map$1aqm6sp, map$04ry0e1 as option_map$04ry0e1, mapOr$135q041 as option_mapOr$135q041, mapOr$17z0l8m as option_mapOr$17z0l8m, or$0as8tia as option_or$0as8tia, zip$0wdt346, clone$1omlcob as option_clone$1omlcob } from "./core/option.ts"; import * as Counted from "./slices.Counted.ts"; import type * as Held$item_writes from "./slices.Held$item_writes.ts"; import * as Item from "./slices.Item.ts"; @@ -2424,9 +2424,9 @@ export function arraysMut(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): voi rs.idx(_307[1], _315); const slice10 = rs.arraySliceAt(_307[0], 0); const slice11 = rs.arraySliceAt(_307[1], _315); - rs.sliceSet(slice11, rs.replaceIn(rs.sliceView(slice10), rs.sliceToArray(slice11))); + rs.sliceSet(slice11, rs.sliceReplaceAll(slice10, rs.sliceToArray(slice11))); rs.idx(_253[1], 0); - const old2: rs.u16[] = rs.replaceIn(rs.sliceView(rs.arraySliceAt(_253[1], 0)), [7, 8]); + const old2: rs.u16[] = rs.sliceReplaceAll(rs.arraySliceAt(_253[1], 0), [7, 8]); const _327: rs.usize = rs.usizeSub(n2, 1); rs.idx(_253[1], _327); rs.sliceSet(rs.arraySliceAt(_253[1], _327), copy$array_u16(old2)); @@ -2781,7 +2781,7 @@ export function arraysMut(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): voi const _875: [rs.ArraySlice>, rs.Slice] = rs.sliceAsChunks(rs.sliceFrom(items.items), 2); if (_875[0].length >= 2) { rs.idx(_875[0], 0); - const first7: Item.Item[] = rs.replaceIn(rs.sliceView(rs.arraySliceAt(_875[0], 0)), [new Item.Item(65), new Item.Item(66)], 1); + const first7: Item.Item[] = rs.sliceReplaceAll(rs.arraySliceAt(_875[0], 0), [new Item.Item(65), new Item.Item(66)], 1); flush(out); rs.arraySliceSwap(_875[0], 0, 1, rs.objectCopy); rs.arraySliceBy(_875[0], (arrays) => rs.sliceReverse(arrays), rs.objectCopy); @@ -2804,7 +2804,7 @@ export function arraysMut(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): voi rs.idx(_909[1], 0); const slice6 = rs.arraySliceAt(_909[0], 0); const slice7 = rs.arraySliceAt(_909[1], 0); - rs.sliceSet(slice7, rs.replaceIn(rs.sliceView(slice6), rs.sliceToArray(slice7), 1)); + rs.sliceSet(slice7, rs.sliceReplaceAll(slice6, rs.sliceToArray(slice7), 1)); rs.iterExtendBytes(out, rs.iterMap(rs.arraySliceIter(_875[0]), (c2: rs.Slice): rs.u8 => { return _11(c2); }), undefined, true); @@ -2965,8 +2965,13 @@ export function arrayForms(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): vo const runs2: rs.ArraySlice> = rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => item, (value) => item = value)), 1); rs.idx(runs2, 0); const _354: rs.ByteVec[] = [rs.byteVecFrom(Uint8Array.of(byte(1), byte(2)))]; - rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(rs.replaceIn(rs.sliceView(rs.arraySliceAt(runs2, 0)), _354, 1)[0])), undefined, true); - rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(rs.cellReplace(rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => item, (value2) => item = value2)), 1), rs.objectCopy), [[rs.byteVecFrom(Uint8Array.of(byte(3)))]])[0][0])), undefined, true); + rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(rs.sliceReplaceAll(rs.arraySliceAt(runs2, 0), _354, 1)[0])), undefined, true); + const _367: rs.Cell = rs.cellOfArraySlice(rs.arraySliceOne(rs.sliceOfPlace(rs.place(() => item, (value2) => item = value2)), 1), rs.objectCopy); + const _371: rs.ByteVec[][] = [[rs.byteVecFrom(Uint8Array.of(byte(3)))]]; + const pointer = rs.cellArray(_367, rs.arraySliceOf(rs.sliceFrom)); + const old4 = rs.arraySliceCopy(pointer, rs.objectCopy); + rs.arraySliceSet(pointer, _371); + rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(old4[0][0])), undefined, true); rs.iterExtendBytes(out, rs.iterSlice(rs.byteVecView(item)), undefined, true); } } @@ -3151,28 +3156,25 @@ export function arraySources(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): const row: (a0: rs.usize) => Uint8Array = (at: rs.usize): Uint8Array => { return option_unwrapOr$1la41a6(copy$Option_array2_u8(rs.optionMap(rs.arraySliceGet(rs.arraySliceFrom(rows.items, rs.byteSliceFrom), at), rs.byteSliceView)), rs.bytes(2).fill(at & 0xff)); }; - const grid: Uint8Array[] = [row(0), row(1), row(2)]; - const wrapped: Uint8Array[] = rs.arraySliceItems(rs.arraySliceFrom([Uint8Array.of(grid[2][1], grid[0][0]), Uint8Array.of(grid[1][0], grid[2][0]), Uint8Array.of(grid[0][1], grid[1][1]), copy$array_u8(grid[2])], rs.byteSliceFrom)); - rs.iterExtendBytes(out, rs.iterFlatten(rs.arraySliceIter(rs.arraySliceOf(rs.byteSliceFrom)(wrapped)), (value: rs.ByteSlice) => rs.iterSlice(rs.byteSliceView(value)), true, 2), undefined, true); - const cow: rs.Cow> = new rs.Borrowed(rs.arraySliceRange(rs.arraySliceFrom(grid, rs.byteSliceFrom), 1)); + const cow: rs.Cow> = new rs.Borrowed(rs.arraySliceRange(rs.arraySliceFrom([row(0), row(1), row(2)], rs.byteSliceFrom), 1)); if (cow instanceof rs.Borrowed) { - const _217: rs.u8 = (cow as rs.Borrowed>).slice.length & 0xff; + const _171: rs.u8 = (cow as rs.Borrowed>).slice.length & 0xff; rs.idx((cow as rs.Borrowed>).slice, 0); const slice2 = rs.arraySliceAt((cow as rs.Borrowed>).slice, 0); - const _219: rs.u8 = slice2.data[slice2.start]; - const _226: rs.usize = rs.usizeSub((cow as rs.Borrowed>).slice.length, 1); - rs.idx((cow as rs.Borrowed>).slice, _226); - const slice4 = rs.arraySliceAt((cow as rs.Borrowed>).slice, _226); - rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(_217, _219, slice4.data[slice4.start + 1])), undefined, true); + const _173: rs.u8 = slice2.data[slice2.start]; + const _180: rs.usize = rs.usizeSub((cow as rs.Borrowed>).slice.length, 1); + rs.idx((cow as rs.Borrowed>).slice, _180); + const slice4 = rs.arraySliceAt((cow as rs.Borrowed>).slice, _180); + rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(_171, _173, slice4.data[slice4.start + 1])), undefined, true); } else { rs.byteVecPush(out, (cow as rs.Vec).items.length & 0xff); } } else { const leaked: rs.ArraySlice = rs.arraySliceFrom(rs.vecFrom(rows.items.map(copy$array_u8)).items, rs.byteSliceFrom); - const _240: rs.ByteSlice | undefined = rs.arraySliceFirst(leaked); - if (_240 !== undefined) { - const _243: rs.u8 = rs.u8WrappingAdd(_240.data[_240.start], 1); - _240.data[_240.start] = _243; + const _194: rs.ByteSlice | undefined = rs.arraySliceFirst(leaked); + if (_194 !== undefined) { + const _197: rs.u8 = rs.u8WrappingAdd(_194.data[_194.start], 1); + _194.data[_194.start] = _197; } rs.iterExtendBytes(out, rs.iterFlatten(rs.arraySliceIter(leaked), (value: rs.ByteSlice) => rs.iterSlice(rs.byteSliceView(value)), true, 2), undefined, true); } @@ -3477,4 +3479,165 @@ export function rowLen(cut: rs.usize): rs.u8 { return (cut & 0xff) | 1; } +/** Puts each word's low byte. */ +export function putWords(words: rs.Slice, out: rs.ByteVec): void { + rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(rs.sliceItems(words)), (_2: rs.u32): rs.u8 => { + return _2 & 0xff; + }), undefined, true); +} + +/** + * A `&mut [T; N]` to part of a slice, of numbers, of strings, and of arrays, written whole: + * by `mem::replace` and `mem::swap`, and through a `Cell` and an `UnsafeCell` of it, each + * way a cell reads, writes, and points at it; a cell of arrays pointed at before a write, + * and of pinned boxes, whose replacement keeps their allocations; and one std holds in an `Option` and a `Vec` and writes through. + */ +export function arrayParts(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { + const words: rs.Vec = rs.iterToVec(rs.iterMap(rs.iterSlice(rs.byteSliceView(data)), (_2: rs.u8): rs.u32 => { + return _2 as rs.u32; + }), undefined, 4, true); + rs.vecResize(words, rs.max(words.items.length, 6), 9, 4, undefined); + const names: rs.Vec = rs.iterToVec(rs.iterMap(rs.iterSlice(rs.byteSliceView(data)), (b2: rs.u8): rs.String => { + return rs.fmtToString((f: rs.Formatter) => rs.u8Display(b2, f), 0); + }), undefined, 12, true); + const _17: rs.usize = rs.max(names.items.length, 6); + const _20: rs.String = rs.stringFrom("z"); + rs.vecResize(names, _17, _20, 12, (a0: rs.String): rs.String => { + return rs.stringClone(a0); + }); + const rows: rs.Vec = rs.iterToVec(rs.iterMap(rs.sliceChunks(rs.sliceFrom(words.items), 2), (c: rs.Slice): rs.u32[] => { + rs.idx(c, 0); + const _3: rs.u32 = c.data[c.start]; + const _8: rs.usize = rs.usizeSub(c.length, 1); + rs.idx(c, _8); + return [_3, c.data[c.start + _8]]; + }), undefined, 8, true); + const n: rs.u32 = kind as rs.u32; + const _27: rs.u8 = rs.u8Rem(kind, 4); + if (_27 === 0) { + const _31: [rs.Slice, rs.Slice] = rs.sliceSplitAt(rs.sliceFrom(words.items), 1); + putWords(rs.sliceFrom(rs.sliceReplaceAll(rs.optionUnwrap(rs.sliceGetRange(_31[1], 0, 2)), [n, rs.u32Add(n, 1)])), out); + const _45: [rs.Slice, rs.Slice] = rs.optionUnwrap(rs.sliceSplitAtChecked(rs.sliceRange(_31[1], 2), 2)); + const y: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(_45[1], 0, 2)); + rs.sliceSet(y, rs.sliceReplaceAll(_45[0], rs.sliceToArray(y))); + rs.idx(_31[0], 0); + _31[0].data[_31[0].start] = n; + const s: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(names.items), 1), 0, 2)); + const _62: rs.String[] = [rs.stringFrom("a"), rs.stringFrom("b")]; + rs.iterExtendBytes(out, rs.iterMap(rs.iterMap(rs.iterSlice(rs.sliceReplaceAll(s, _62, 1)), (a03: rs.String): rs.usize => { + return a03.len; + }), (l2: rs.usize): rs.u8 => { + return l2 & 0xff; + }), undefined, true); + } else if (_27 === 1) { + const cell: rs.Cell = rs.cellOfSlice(rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 1), 0, 2))); + const _78: rs.u32[] = [n, rs.u32Add(n, 2)]; + const pointer3 = rs.cellArray(cell, rs.sliceFrom); + const old9 = rs.sliceCopy(pointer3); + rs.sliceSet(pointer3, _78); + putWords(rs.sliceFrom(old9), out); + putWords(rs.sliceFrom(copy$array_u32(cell.v)), out); + const _89: rs.u32[] = [rs.u32Add(n, 3), rs.u32Add(n, 4)]; + rs.sliceSet(rs.cellArray(cell, rs.sliceFrom), _89); + const p: rs.Slice = rs.cellArray(cell, rs.sliceFrom); + p.data[p.start + 1] = rs.u32Add(n, 5); + const pointer4 = rs.cellArray(cell, rs.sliceFrom); + rs.sliceSet(pointer4, ((_29: rs.u32[]): rs.u32[] => { + return [_29[1], _29[0]]; + })(rs.sliceToArray(pointer4))); + const value2 = Array.from({ length: 2 }, (): rs.u32 => { + return 0; + }); + const pointer5 = rs.cellArray(cell, rs.sliceFrom); + const old10 = rs.sliceCopy(pointer5); + rs.sliceSet(pointer5, value2); + putWords(rs.sliceFrom(old10), out); + const _109: rs.Cell = rs.cellOfSlice(rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(names.items), 2), 0, 2))); + const _110: rs.String[] = [rs.stringFrom("abc"), rs.stringNew()]; + const pointer6 = rs.cellArray(_109, rs.sliceFrom); + const old11 = rs.sliceCopy(pointer6, 1); + rs.sliceSet(pointer6, _110); + rs.iterExtendBytes(out, rs.iterMap(rs.iterMap(rs.iterSlice(old11), (a02: rs.String): rs.usize => { + return a02.len; + }), (l: rs.usize): rs.u8 => { + return l & 0xff; + }), undefined, true); + const cell2: rs.Cell = rs.cellOfSlice(rs.optionUnwrap(rs.sliceGetRange(rs.sliceRange(rs.sliceFrom(words.items), 2), 0, 2))); + const _125: rs.u32 = rs.u32Add(n, 6); + const _126: rs.Slice = rs.cellArray(cell2, rs.sliceFrom); + _126.data[_126.start] = _125; + const _130: rs.u32 = rs.u32Add(n, 7); + const _131: rs.Slice = rs.cellArray(cell2, rs.sliceFrom); + _131.data[_131.start + 1] = _130; + } else if (_27 === 2) { + const cell3: rs.Cell = rs.cellOfArraySlice(rs.optionUnwrap(rs.arraySliceGetRange(rs.arraySliceRange(rs.arraySliceFrom(rows.items, rs.sliceFrom), 1), 0, 2))); + const p2: rs.ArraySlice> = rs.cellArray(cell3, rs.arraySliceOf(rs.sliceFrom)); + const _141: rs.u32 = rs.u32Add(n, 6); + const slice3 = rs.arraySliceAt(p2, 0); + slice3.data[slice3.start + 1] = _141; + const _147: rs.u32[][] = [[n, rs.u32Add(n, 7)], [rs.u32Add(n, 8), n]]; + const pointer = rs.cellArray(cell3, rs.arraySliceOf(rs.sliceFrom)); + const old7 = rs.arraySliceCopy(pointer); + rs.arraySliceSet(pointer, _147); + rs.iterExtendBytes(out, rs.iterMap(rs.iterFlatten(rs.arraySliceIter(rs.arraySliceFrom(old7, rs.sliceFrom)), (value: rs.Slice) => rs.iterSlice(rs.sliceItems(value)), true, 2), (_25: rs.u32): rs.u8 => { + return _25 & 0xff; + }), undefined, true); + const cell4: rs.Cell = rs.cellOfArraySlice(rs.optionUnwrap(rs.arraySliceGetRange(rs.arraySliceRange(rs.arraySliceFrom(rows.items, rs.sliceFrom), 0, 2), 0, 2))); + const _166: rs.u32 = rs.u32Add(n, 9); + const slice5 = rs.arraySliceAt(rs.cellArray(cell4, rs.arraySliceOf(rs.sliceFrom)), 1); + slice5.data[slice5.start] = _166; + const _173: rs.u32 = rs.u32Add(n, 10); + const slice6 = rs.arraySliceAt(rs.cellArray(cell4, rs.arraySliceOf(rs.sliceFrom)), 0); + slice6.data[slice6.start] = _173; + const held: rs.Cell = new rs.Cell([[n, 1], [2, n]]); + const p3: rs.ArraySlice> = rs.cellArray(held, rs.arraySliceOf(rs.sliceFrom)); + const _187: rs.u32[][] = [[3, n], [n, 4]]; + rs.arraySliceSet(rs.cellArray(held, rs.arraySliceOf(rs.sliceFrom)), _187); + rs.iterExtendBytes(out, rs.iterMap(rs.iterFlatten(rs.arraySliceIter(rs.arraySliceFrom(rs.arraySliceToArray(p3, rs.sliceToArray), rs.sliceFrom)), (value: rs.Slice) => rs.iterSlice(rs.sliceItems(value)), true, 2), (_26: rs.u32): rs.u8 => { + return _26 & 0xff; + }), undefined, true); + const pinned: [rs.u8, rs.u8] = [n & 0xff, 1]; + const at: [rs.u8, rs.u8] = pinned; + const boxes: rs.Cell<[rs.u8, rs.u8][][]> = new rs.Cell([[pinned]]); + const _209: [rs.u8, rs.u8][][] = [[[2, n & 0xff] as [rs.u8, rs.u8]]]; + const pointer2 = rs.cellArray(boxes, rs.arraySliceOf(rs.sliceFrom)); + const old8 = rs.arraySliceCopy(pointer2, rs.objectCopy); + rs.arraySliceSet(pointer2, _209); + const old6: [rs.u8, rs.u8] = old8[0][0]; + rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(at === old6 ? 1 : 0, old6[0])), undefined, true); + } else { + const _226: [rs.Slice, rs.Slice] = rs.optionUnwrap(rs.sliceSplitAtChecked(rs.sliceRange(rs.sliceFrom(words.items), 1), 2)); + rs.idx(_226[1], 0); + _226[1].data[_226[1].start] = n; + let kept: rs.Slice | undefined = _226[0]; + const _236: rs.Place> | undefined = kept === undefined ? undefined : rs.place(() => kept as rs.Slice, (value) => kept = value); + if (_236 !== undefined) { + const _240: rs.u32 = rs.u32Add(n, 1); + const _285: rs.Slice = _236.v; + _285.data[_285.start] = _240; + } + option_map$0cigbgc(kept, (a4: rs.Slice): undefined => { + a4.data[a4.start + 1] = rs.u32Add(n, 2); + }); + const v: rs.Vec> = new rs.Vec(); + const _250: [rs.Slice, rs.Slice] = rs.sliceSplitAt(rs.sliceFrom(words.items), 2); + const _255: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(_250[1], 0, 2)); + v.items.push(_255); + const _259: rs.Slice = rs.optionUnwrap(rs.sliceGetRange(_250[0], 0, 2)); + v.items.push(_259); + for (const _264 of v.items) { + rs.sliceSwap(_264, 0, 1); + } + } + putWords(rs.sliceFrom(words.items), out); + rs.iterExtendBytes(out, rs.iterMap(rs.iterMap(rs.iterSlice(names.items), (a04: rs.String): rs.usize => { + return a04.len; + }), (l3: rs.usize): rs.u8 => { + return l3 & 0xff; + }), undefined, true); + rs.iterExtendBytes(out, rs.iterMap(rs.iterFlatten(rs.arraySliceIter(rs.arraySliceFrom(rows.items, rs.sliceFrom)), (value: rs.Slice) => rs.iterSlice(rs.sliceItems(value)), true, 2), (_214: rs.u32): rs.u8 => { + return _214 & 0xff; + }), undefined, true); +} + //# sourceMappingURL=slices.ts.map diff --git a/ts/fixtures/lang/slices/src/lib.rs b/ts/fixtures/lang/slices/src/lib.rs index 630056474..3f713cd77 100644 --- a/ts/fixtures/lang/slices/src/lib.rs +++ b/ts/fixtures/lang/slices/src/lib.rs @@ -28,5 +28,6 @@ fn cases() -> Vec<(&'static str, Case)> { ("slices::array_identity", slices::array_identity), ("slices::array_sources", slices::array_sources), ("slices::item_writes", slices::item_writes), + ("slices::array_parts", slices::array_parts), ] } diff --git a/ts/fixtures/lang/slices/src/slices.rs b/ts/fixtures/lang/slices/src/slices.rs index e4b75aedc..302505b37 100644 --- a/ts/fixtures/lang/slices/src/slices.rs +++ b/ts/fixtures/lang/slices/src/slices.rs @@ -7,7 +7,8 @@ //! place, of values that log as they are cloned and drop; and a slice's runs as arrays, //! and a `Vec` cloned from a slice; and slices of arrays in each form they take: constants, //! defaults, an `Option`'s, a `Cow`'s, a generic struct's, clones, and runs of references -//! and of wrapped arrays. +//! and of wrapped arrays; and a mutable reference to part of a slice as an array, written +//! whole. use std::cell::RefCell; @@ -1612,22 +1613,10 @@ pub fn array_sources(kind: u8, data: &[u8], out: &mut Vec) { let shared: std::rc::Rc<[[u8; 2]]> = rows.clone().into(); out.extend(shared.iter().rev().flatten()); } - // A reborrow of a `MaybeUninit` of an array of arrays through a raw pointer, and a - // borrowed `Cow`'s, matched. + // A borrowed `Cow`'s, matched. 3 => { let row = |at: usize| rows.get(at).copied().unwrap_or([at as u8; 2]); let grid = [row(0), row(1), row(2)]; - let pairs = [ - [grid[2][1], grid[0][0]], - [grid[1][0], grid[2][0]], - [grid[0][1], grid[1][1]], - grid[2], - ]; - let p = (&pairs as *const [[u8; 2]; 4]).cast::>(); - // SAFETY: `p` points at `pairs`, which is initialized and outlives the borrow. - let wrapped = unsafe { &*p }; - // SAFETY: as above. - out.extend(unsafe { wrapped.assume_init_ref() }.iter().flatten()); let cow: std::borrow::Cow<'_, [[u8; 2]]> = std::borrow::Cow::Borrowed(&grid[1..]); match cow { std::borrow::Cow::Borrowed(rows) => out.extend([rows.len() as u8, rows[0][0], rows[rows.len() - 1][1]]), @@ -1805,3 +1794,96 @@ pub fn item_writes(kind: u8, data: &[u8], out: &mut Vec) { fn row_len(cut: usize) -> u8 { cut as u8 | 1 } + +/// Puts each word's low byte. +fn put_words(words: &[u32], out: &mut Vec) { + out.extend(words.iter().map(|&w| w as u8)); +} + +/// A `&mut [T; N]` to part of a slice, of numbers, of strings, and of arrays, written whole: +/// by `mem::replace` and `mem::swap`, and through a `Cell` and an `UnsafeCell` of it, each +/// way a cell reads, writes, and points at it; a cell of arrays pointed at before a write, +/// and of pinned boxes, whose replacement keeps their allocations; and one std holds in an `Option` and a `Vec` and writes through. +pub fn array_parts(kind: u8, data: &[u8], out: &mut Vec) { + use std::cell::{Cell, UnsafeCell}; + let mut words: Vec = data.iter().map(|&b| u32::from(b)).collect(); + words.resize(words.len().max(6), 9); + let mut names: Vec = data.iter().map(|b| b.to_string()).collect(); + names.resize(names.len().max(6), String::from("z")); + let mut rows: Vec<[u32; 2]> = words.chunks(2).map(|c| [c[0], c[c.len() - 1]]).collect(); + let n = u32::from(kind); + match kind % 4 { + 0 => { + let (head, rest) = words.split_at_mut(1); + let a: &mut [u32; 2] = rest.first_chunk_mut().unwrap(); + let old = std::mem::replace(a, [n, n + 1]); + put_words(&old, out); + let (x, y) = rest[2..].split_first_chunk_mut::<2>().unwrap(); + let y: &mut [u32; 2] = y.first_chunk_mut().unwrap(); + std::mem::swap(x, y); + head[0] = n; + let s: &mut [String; 2] = names[1..].first_chunk_mut().unwrap(); + let old = std::mem::replace(s, [String::from("a"), String::from("b")]); + out.extend(old.iter().map(String::len).map(|l| l as u8)); + } + 1 => { + let a: &mut [u32; 2] = words[1..].first_chunk_mut().unwrap(); + let cell = Cell::from_mut(a); + let old = cell.replace([n, n + 2]); + put_words(&old, out); + put_words(&cell.get(), out); + cell.set([n + 3, n + 4]); + let p = cell.as_ptr(); + unsafe { (*p)[1] = n + 5 }; + cell.update(|[x, y]| [y, x]); + put_words(&cell.take(), out); + let s: &mut [String; 2] = names[2..].first_chunk_mut().unwrap(); + let old = Cell::from_mut(s).replace([String::from("abc"), String::new()]); + out.extend(old.iter().map(String::len).map(|l| l as u8)); + let a: &mut [u32; 2] = words[2..].first_chunk_mut().unwrap(); + let cell = UnsafeCell::from_mut(a); + unsafe { (*cell.get())[0] = n + 6 }; + cell.get_mut()[1] = n + 7; + } + 2 => { + let r: &mut [[u32; 2]; 2] = rows[1..].first_chunk_mut().unwrap(); + let cell = Cell::from_mut(r); + let p = cell.as_ptr(); + unsafe { (*p)[0][1] = n + 6 }; + let old = cell.replace([[n, n + 7], [n + 8, n]]); + out.extend(old.iter().flatten().map(|&w| w as u8)); + let r: &mut [[u32; 2]; 2] = rows[..2].first_chunk_mut().unwrap(); + let cell = UnsafeCell::from_mut(r); + unsafe { (*cell.get())[1][0] = n + 9 }; + cell.get_mut()[0][0] = n + 10; + let held = Cell::new([[n, 1], [2, n]]); + let p = held.as_ptr(); + held.set([[3, n], [n, 4]]); + out.extend(unsafe { *p }.iter().flatten().map(|&w| w as u8)); + let pinned = Box::pin((n as u8, 1)); + let at: *const (u8, u8) = &*pinned; + let boxes = Cell::new([[pinned]]); + let [[old]] = boxes.replace([[Box::pin((2, n as u8))]]); + out.extend([u8::from(std::ptr::eq(at, &*old)), old.0]); + } + _ => { + let (a, b) = words[1..].split_first_chunk_mut::<2>().unwrap(); + b[0] = n; + let mut kept = Some(a); + if let Some(a) = kept.as_mut() { + a[0] = n + 1; + } + kept.map(|a| a[1] = n + 2); + let mut v: Vec<&mut [u32; 2]> = Vec::new(); + let (d, rest) = words.split_at_mut(2); + v.push(rest.first_chunk_mut().unwrap()); + v.push(d.first_chunk_mut().unwrap()); + for a in v { + a.swap(0, 1); + } + } + } + put_words(&words, out); + out.extend(names.iter().map(String::len).map(|l| l as u8)); + out.extend(rows.iter().flatten().map(|&w| w as u8)); +} diff --git a/ts/fixtures/reject/census.txt b/ts/fixtures/reject/census.txt index 1348aba69..84558557f 100644 --- a/ts/fixtures/reject/census.txt +++ b/ts/fixtures/reject/census.txt @@ -6,13 +6,14 @@ fixtures/reject/src/alloc.rs:alloc_retyped+8:21: memory from `alloc` cast to poi fixtures/reject/src/alloc.rs:alloc_retyped+10:17: memory from `alloc` cast to pointers to `i32` and to `u32`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:allocated+4:3: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as fixtures/reject/src/alloc.rs:allocated+5:11: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as +fixtures/reject/src/alloc.rs:arrays_boxed+4:22: `Box::from_raw` of `[[u32; 2]; 2]`, which may be arrays `as_chunks` split from one flat array, which is not supported yet +fixtures/reject/src/alloc.rs:arrays_boxed+6:23: `Box::from_raw` of `[alloc::Only; 2]`, a value of no bytes made of more than structs and tuples fixtures/reject/src/alloc.rs:bytes_as_values+3:3: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as fixtures/reject/src/alloc.rs:bytes_as_values+4:15: a cast from a pointer to `u8` to one to `u32`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:bytes_as_values+5:16: a cast from a pointer to `u8` to one to `pointers::Halves`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:bytes_as_values+7:15: a cast from a pointer to `u32` to one to `u8`, which reads the bytes of one type as another -fixtures/reject/src/alloc.rs:cell_of_arrays+1:10: `UnsafeCell::from_mut` of `[[u16; 2]; 2]`, an array of arrays, which a cell of it reads a copy of, so a write through its pointer would land in the copy -fixtures/reject/src/alloc.rs:cell_of_arrays+7:4: `Cell::swap` of `[[u16; 2]; 2]`, an array, whose cells may partially overlap, which Rust panics on -fixtures/reject/src/alloc.rs:cell_of_arrays+9:4: `Cell::swap` of `[u32; 2]`, an array, whose cells may partially overlap, which Rust panics on +fixtures/reject/src/alloc.rs:cell_of_arrays+5:4: `Cell::swap` of `[[u16; 2]; 2]`, an array, whose cells may partially overlap, which Rust panics on +fixtures/reject/src/alloc.rs:cell_of_arrays+7:4: `Cell::swap` of `[u32; 2]`, an array, whose cells may partially overlap, which Rust panics on fixtures/reject/src/alloc.rs:cell_of_objects+1:10: `UnsafeCell::from_mut` of `std::vec::Vec`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address fixtures/reject/src/alloc.rs:cell_of_objects+2:10: `UnsafeCell::from_mut` of `std::string::String`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address fixtures/reject/src/alloc.rs:cell_of_objects+3:10: `UnsafeCell::from_mut` of `std::pin::Pin>`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address @@ -33,6 +34,12 @@ fixtures/reject/src/alloc.rs:cell_raw_unknown+9:13: `UnsafeCell::raw_get` of a p fixtures/reject/src/alloc.rs:pinned_lent+1:32: `UnsafeCell::get_mut` of `std::pin::Pin>`, an object a whole write through the reference changes in place, so a value read out before would be a copy at another address fixtures/reject/src/alloc.rs:pinned_lent+2:43: `UnsafeCell::as_mut_unchecked` of `std::pin::Pin>`, an object a whole write through the reference changes in place, so a value read out before would be a copy at another address fixtures/reject/src/alloc.rs:reinterpreted+1:27: a cast from a pointer to `u32` to one to `u8`, which reads the bytes of one type as another +fixtures/reject/src/alloc.rs:uninit_array_lent+1:25: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+2:59: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+3:25: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+4:59: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+5:23: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+6:23: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet fixtures/reject/src/alloc.rs:uninit_cell_lent+2:17: `MaybeUninit::assume_init_mut` of `std::cell::UnsafeCell`, whose mutable reference is the object, but the uninitialized value's is the place it is kept in fixtures/reject/src/alloc.rs:vec_pointer+1:10: a raw pointer to `std::vec::Vec` behind a reference, which is the object and not where it is kept fixtures/reject/src/alloc.rs:wrapped_cells+8:19: a whole write of `std::mem::MaybeUninit<(std::cell::UnsafeCell, u32)>`, which would put another cell in place of one a `MaybeUninit` or `ManuallyDrop` holds @@ -250,10 +257,10 @@ fixtures/reject/src/pointers.rs:reached_out+8:27: a pointer reaching past a valu fixtures/reject/src/pointers.rs:text_apart+1:27: `offset_from` between pointers of two `str::as_ptr` calls, each into an encoding of the text of its own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:text_apart+1:64: `offset_from` between pointers of two `str::as_ptr` calls, each into an encoding of the text of its own, which JS keeps in different arrays fixtures/reject/src/pointers.rs:text_before+1:28: a pointer reaching past a `str`'s bytes, which JS keeps apart from what holds it in Rust -fixtures/reject/src/pointers.rs:uninit_part_mut+5:25: a mutable reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own, which is not supported yet +fixtures/reject/src/pointers.rs:uninit_part_mut+5:25: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet fixtures/reject/src/pointers.rs:uninit_part_replaced+5:19: a raw pointer to `std::mem::MaybeUninit<(u32, u32)>` in `pointers::Gap`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:uninit_part_replaced+6:19: a raw pointer to `std::mem::MaybeUninit<(u32, u32)>` in `pointers::Gap`, which the crate may put another object in place of -fixtures/reject/src/pointers.rs:uninit_rows_mut+5:25: a mutable reborrow of `std::mem::MaybeUninit<[[u8; 2]; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own, which is not supported yet +fixtures/reject/src/pointers.rs:uninit_rows_mut+5:25: a reborrow of `std::mem::MaybeUninit<[[u8; 2]; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet fixtures/reject/src/pointers.rs:unit_elements+1:13: `offset_from` of pointers to `()`, which has no bytes fixtures/reject/src/pointers.rs:unit_elements+1:39: a slice of `()`, which has no bytes, from a pointer fixtures/reject/src/pointers.rs:variable_celled+2:10: a raw pointer to `(u32, u32)` in a variable assigned again while it may point there diff --git a/ts/fixtures/reject/expected.txt b/ts/fixtures/reject/expected.txt index 0322a77c5..c2eae6dd6 100644 --- a/ts/fixtures/reject/expected.txt +++ b/ts/fixtures/reject/expected.txt @@ -10,13 +10,14 @@ fixtures/reject/src/alloc.rs:alloc_retyped+8:21: memory from `alloc` cast to poi fixtures/reject/src/alloc.rs:alloc_retyped+10:17: memory from `alloc` cast to pointers to `i32` and to `u32`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:allocated+4:3: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as fixtures/reject/src/alloc.rs:allocated+5:11: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as +fixtures/reject/src/alloc.rs:arrays_boxed+4:22: `Box::from_raw` of `[[u32; 2]; 2]`, which may be arrays `as_chunks` split from one flat array, which is not supported yet +fixtures/reject/src/alloc.rs:arrays_boxed+6:23: `Box::from_raw` of `[alloc::Only; 2]`, a value of no bytes made of more than structs and tuples fixtures/reject/src/alloc.rs:bytes_as_values+3:3: a byte of memory from `alloc`, which JS keeps as the values a cast of its pointer types it as fixtures/reject/src/alloc.rs:bytes_as_values+4:15: a cast from a pointer to `u8` to one to `u32`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:bytes_as_values+5:16: a cast from a pointer to `u8` to one to `pointers::Halves`, which reads the bytes of one type as another fixtures/reject/src/alloc.rs:bytes_as_values+7:15: a cast from a pointer to `u32` to one to `u8`, which reads the bytes of one type as another -fixtures/reject/src/alloc.rs:cell_of_arrays+1:10: `UnsafeCell::from_mut` of `[[u16; 2]; 2]`, an array of arrays, which a cell of it reads a copy of, so a write through its pointer would land in the copy -fixtures/reject/src/alloc.rs:cell_of_arrays+7:4: `Cell::swap` of `[[u16; 2]; 2]`, an array, whose cells may partially overlap, which Rust panics on -fixtures/reject/src/alloc.rs:cell_of_arrays+9:4: `Cell::swap` of `[u32; 2]`, an array, whose cells may partially overlap, which Rust panics on +fixtures/reject/src/alloc.rs:cell_of_arrays+5:4: `Cell::swap` of `[[u16; 2]; 2]`, an array, whose cells may partially overlap, which Rust panics on +fixtures/reject/src/alloc.rs:cell_of_arrays+7:4: `Cell::swap` of `[u32; 2]`, an array, whose cells may partially overlap, which Rust panics on fixtures/reject/src/alloc.rs:cell_of_objects+1:10: `UnsafeCell::from_mut` of `std::vec::Vec`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address fixtures/reject/src/alloc.rs:cell_of_objects+2:10: `UnsafeCell::from_mut` of `std::string::String`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address fixtures/reject/src/alloc.rs:cell_of_objects+3:10: `UnsafeCell::from_mut` of `std::pin::Pin>`, an object a whole write through it changes in place, so a value read out before would change too or be a copy at another address @@ -37,6 +38,12 @@ fixtures/reject/src/alloc.rs:cell_raw_unknown+9:13: `UnsafeCell::raw_get` of a p fixtures/reject/src/alloc.rs:pinned_lent+1:32: `UnsafeCell::get_mut` of `std::pin::Pin>`, an object a whole write through the reference changes in place, so a value read out before would be a copy at another address fixtures/reject/src/alloc.rs:pinned_lent+2:43: `UnsafeCell::as_mut_unchecked` of `std::pin::Pin>`, an object a whole write through the reference changes in place, so a value read out before would be a copy at another address fixtures/reject/src/alloc.rs:reinterpreted+1:27: a cast from a pointer to `u32` to one to `u8`, which reads the bytes of one type as another +fixtures/reject/src/alloc.rs:uninit_array_lent+1:25: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+2:59: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+3:25: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+4:59: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+5:23: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet +fixtures/reject/src/alloc.rs:uninit_array_lent+6:23: a reborrow of `std::mem::MaybeUninit<[u32; 2]>` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet fixtures/reject/src/alloc.rs:uninit_cell_lent+2:17: `MaybeUninit::assume_init_mut` of `std::cell::UnsafeCell`, whose mutable reference is the object, but the uninitialized value's is the place it is kept in fixtures/reject/src/alloc.rs:vec_pointer+1:10: a raw pointer to `std::vec::Vec` behind a reference, which is the object and not where it is kept fixtures/reject/src/alloc.rs:wrapped_cells+8:19: a whole write of `std::mem::MaybeUninit<(std::cell::UnsafeCell, u32)>`, which would put another cell in place of one a `MaybeUninit` or `ManuallyDrop` holds diff --git a/ts/fixtures/reject/src/alloc.rs b/ts/fixtures/reject/src/alloc.rs index d3ec2b5ea..723532aee 100644 --- a/ts/fixtures/reject/src/alloc.rs +++ b/ts/fixtures/reject/src/alloc.rs @@ -134,11 +134,8 @@ pub fn wrapped_cells(n: u32) -> u32 { } } -/// An `UnsafeCell::from_mut` of arrays of arrays, which a cell may read a copy of, and /// `Cell::swap`s of arrays, whose cells may partially overlap. -pub fn cell_of_arrays(a: &mut [[u16; 2]; 2]) -> u16 { - let c = std::cell::UnsafeCell::from_mut(a); - let first = unsafe { (*c.get())[0][0] }; +pub fn cell_of_arrays() -> u16 { let (x, y) = ( std::cell::Cell::new([[1u16, 2]; 2]), std::cell::Cell::new([[3u16, 4]; 2]), @@ -146,7 +143,39 @@ pub fn cell_of_arrays(a: &mut [[u16; 2]; 2]) -> u16 { x.swap(&y); let (v, w) = (std::cell::Cell::new([5u32, 6]), std::cell::Cell::new([7u32, 8])); v.swap(&w); - first ^ x.into_inner()[0][0] ^ v.into_inner()[0] as u16 + x.into_inner()[0][0] ^ v.into_inner()[0] as u16 +} + +/// Reborrows through a pointer to an array a `MaybeUninit` holds, by `as_mut`, `as_ref`, +/// and `&*p`, shared and mutable, whose reference is the array, which part of an array has +/// none of its own. +pub fn uninit_array_lent(p: *mut std::mem::MaybeUninit<[u32; 2]>) -> u32 { + let first = unsafe { p.as_mut() }.map_or(0, |m| unsafe { m.assume_init_mut()[0] }); + let second = unsafe { std::ptr::NonNull::new(p).unwrap().as_mut().assume_init_mut()[1] }; + let third = unsafe { p.as_ref() }.map_or(0, |m| unsafe { m.assume_init_ref()[0] }); + let fourth = unsafe { std::ptr::NonNull::new(p).unwrap().as_ref().assume_init_ref()[1] }; + let fifth = unsafe { (&*p).assume_init_ref()[0] }; + let sixth = unsafe { (&mut *p).assume_init_mut()[1] }; + first ^ second ^ third ^ fourth ^ fifth ^ sixth +} + +/// `Box::from_raw` of arrays `as_chunks_mut` split from one flat array, which a box of +/// arrays of their own can't share, and of an array of no bytes whose elements are more than +/// structs and tuples, which the translator can't make anew. +pub fn arrays_boxed() -> u32 { + let flat = Box::into_raw(Box::new([1u32, 2, 3, 4])); + let (runs, _) = unsafe { (*flat).as_chunks_mut::<2>() }; + let whole: *mut [[u32; 2]; 2] = runs.first_chunk_mut().unwrap(); + let back = unsafe { Box::from_raw(whole) }; + let marks = Box::into_raw(Box::new([Only::One; 2])); + let marks = unsafe { Box::from_raw(marks) }; + back[0][0] + marks.len() as u32 +} + +/// An enum of one variant, a value of no bytes. +#[derive(Clone, Copy)] +enum Only { + One, } /// A `get_mut` and an `as_mut_unchecked` of a cell of a pinned `Box`, whose old value diff --git a/ts/fixtures/reject/ts.toml b/ts/fixtures/reject/ts.toml index e71d6f272..5f97a1870 100644 --- a/ts/fixtures/reject/ts.toml +++ b/ts/fixtures/reject/ts.toml @@ -3,6 +3,7 @@ roots = [ "alloc::addressed", "alloc::alloc_retyped", "alloc::allocated", + "alloc::arrays_boxed", "alloc::bytes_as_values", "alloc::cell_of_arrays", "alloc::cell_of_objects", @@ -12,6 +13,7 @@ roots = [ "alloc::cell_raw_unknown", "alloc::pinned_lent", "alloc::reinterpreted", + "alloc::uninit_array_lent", "alloc::uninit_cell_lent", "alloc::vec_pointer", "alloc::wrapped_cells", diff --git a/ts/fixtures/task/expected/drops/called.ts b/ts/fixtures/task/expected/drops/called.ts index 96d79fb7c..b4957ec1a 100644 --- a/ts/fixtures/task/expected/drops/called.ts +++ b/ts/fixtures/task/expected/drops/called.ts @@ -447,7 +447,7 @@ export function called(log: Log.Log, id: rs.u32, arg: rs.u8): void { Log.note(log, rs.fmtFormat(["pair ", args76[0], " ", args76[1]])); return copy$array_u32(p); }; - const pointer = rs.sliceFrom(pair.v); + const pointer = rs.cellArray(pair, rs.sliceFrom); rs.sliceSet(pointer, _510(rs.sliceToArray(pointer))); const part4 = rs.sliceFrom(copy$array_u32(pair.v)); Log.note(log, rs.fmtFormat(["paired ", (f: rs.Formatter) => rs.fmtList(rs.sliceItems(part4), f, rs.u32Debug)])); diff --git a/ts/runtime/rs.ts b/ts/runtime/rs.ts index b02805331..9328504fd 100644 --- a/ts/runtime/rs.ts +++ b/ts/runtime/rs.ts @@ -267,11 +267,10 @@ export type CowOf = Cow | ByteCow | Cow>; export function arrayAsPtr(s: { [i: number]: T }, index = 0): Place { if (s === NULL) return NULL; if (s === DANGLING) return DANGLING; - const view = (s as { [VIEW]?: View })[VIEW]; - const [array, at] = view ? [view.s, view.start + index] : [s, index]; + const array = roomItems(s) ?? s; // Null's is `null`, which `??` would pass over. const from = EMPTY.get(array) as Place | undefined; - return from !== undefined ? from : new AtIndex(array, at); + return from !== undefined ? from : new AtIndex(array, index); } /** The pointer to element `index` of `s`, or `s` if it is null or dangling, as `arrayAsPtr`'s. */ @@ -420,9 +419,9 @@ class Lone implements ProxyHandler { */ function elemOf(p: Place): AtIndex { if (p instanceof AtIndex) { - // A pointer into a mutable part of an array points into the array. - const view = (p.array as { [VIEW]?: View })[VIEW]; - return view ? new AtIndex(view.s, view.start + p.index) : p; + // A pointer into a `Vec`'s storage and its room points into its items. + const items = roomItems(p.array); + return items ? new AtIndex(items, p.index) : p; } if (p === NULL || p === DANGLING) return new AtIndex([] as T[], 0); let lone = LONE.get(p) as T[] | undefined; @@ -695,14 +694,14 @@ export function replaceIn(p: T, value: T, depth = 0): T { /** * A copy of the object `p`, one object deep: its fields, its bytes, or its items for a JS - * array. Its items, and theirs to `depth` levels of arrays, are objects - * a write may land in, as a `sliceIn`'s, which a view of one copies too. + * array. Its items, and theirs to `depth` levels of arrays, are copied where a write may land + * in them, as in a `sliceIn`'s. */ export function objectCopy(p: T, depth = 0): T { if (ArrayBuffer.isView(p)) return (p as unknown as Uint8Array).slice() as T; if (Array.isArray(p)) { const old: unknown[] = p.slice(); - if (depth > 0 && writesIn(p)) for (let i = 0; i < old.length; i++) old[i] = objectCopy(old[i] as object, depth - 1); + if (depth > 0 && ONE.has(p)) for (let i = 0; i < old.length; i++) old[i] = objectCopy(old[i] as object, depth - 1); return old as T; } if (moved(p)) return p.$move(); @@ -899,15 +898,39 @@ export function sliceSet(s: Slice, items: ArrayLike): void { for (let i = 0; i < s.length; i++) s.data[s.start + i] = items[i]; } +/** + * What a `&mut [T; N]`, `s`, points at, as an array of its own: its elements, and theirs to + * `depth` levels of arrays, copied where a write may land in them, as `objectCopy` copies. + */ +export function sliceCopy(s: Slice, depth = 0): T[] { + const old = s.data.slice(s.start, s.start + s.length); + if (depth > 0 && ONE.has(s.data)) for (let i = 0; i < old.length; i++) old[i] = objectCopy(old[i] as object, depth - 1) as T; + return old; +} + +/** `mem::replace` of what a `&mut [T; N]`, `s`, points at: a copy of it, as `sliceCopy` makes, then `items` written where `s` holds them. */ +export function sliceReplaceAll(s: Slice, items: ArrayLike, depth = 0): T[] { + const old = sliceCopy(s, depth); + sliceSet(s, items); + return old; +} + +/** + * `Box::from_raw` of a `*mut [T; N]`, `s`: the array `Box::into_raw` pointed at all of, as a + * box owns all of its allocation. + */ +export function boxArrayFromRaw(s: Slice): T[] { + const all = s instanceof Slice && s.start === 0 && s.length === s.data.length; + return precondition(all ? s.data : undefined, "Box::from_raw requires a pointer Box::into_raw gave"); +} + /** * Whether pointers to a `[T; N]`, slices of its elements, point at the same place: the same - * element of the same array, through any `arrayView` of part of it, or both null. + * element of the same array, through a `Vec`'s view of its storage and room, or both null. */ export function sliceSame(a: Slice, b: Slice): boolean { if (!(a instanceof Slice && b instanceof Slice)) return a === b; - const [x, y] = [(a.data as { [VIEW]?: View })[VIEW], (b.data as { [VIEW]?: View })[VIEW]]; - const [xs, ys] = [x ? x.s : a.data, y ? y.s : b.data]; - return xs === ys && (x ? x.start : 0) + a.start === (y ? y.start : 0) + b.start; + return (roomItems(a.data) ?? a.data) === (roomItems(b.data) ?? b.data) && a.start === b.start; } /** A bounds-checked index into a slice. */ @@ -939,28 +962,6 @@ export function slicePart(s: Slice, start: number, end: number = s.length) return new Slice(s.data, s.start + start, end - start); } -/** - * Elements `start` to `end` of `s` as a JS array whose every element is `s`'s, read and - * written where it is, as a JS array has no views of its own: the `[T; N]` a `&mut` to part - * of an array lends where what takes it writes a JS array. Its own array, holes of the same - * length, answers for the rest, such as `length` and the methods. A view of a view reads - * the array beneath both. - */ -function arrayView(s: T[], start: number, end: number): T[] { - const outer = (s as { [VIEW]?: View })[VIEW]; - const view = outer ? outer.part(start, end - start) : new View(s, start, end - start); - return new Proxy(new Array(end - start), view); -} - -/** - * The `[T; N]` a `&mut [T; N]`, `s`, points at, as a JS array read and written where the - * slice holds it, as a `ByteSlice`'s `Uint8Array` view is: the array itself where the slice - * is all of it, and else a view of its part. - */ -export function sliceView(s: Slice): T[] { - return s.start === 0 && s.length === s.data.length ? s.data : arrayView(s.data, s.start, s.start + s.length); -} - /** `Option::as_slice` of `o`, whose `None` is `none`: its payload, if any, as `slice::from_ref` makes a slice of one. */ export function optionAsSlice(o: T | undefined): Slice; export function optionAsSlice(o: T | None, none: None): Slice; @@ -1040,22 +1041,14 @@ export function byteMirrorFlush(m: ByteMirror | undefined): void { if (byte !== m.last) m.p.v = m.last = byte; } -/** - * Whether a whole write of an element of `s`, an array a slice holds, may land in the object - * there, as one of `sliceIn`'s does, or of a place in one, which only `sliceOfPlace`'s can be. - */ -function writesIn(s: object): boolean { - const view = (s as { [VIEW]?: View })[VIEW]; - return ONE.has(view !== undefined ? view.s : s); -} - /** * `mem::replace` of element `i` of `s`, the array a slice of objects holds them in: what * it held, as an object of its own, copied to `depth` as `objectCopy` copies, where the * write lands in it. */ export function sliceReplace(s: T[], i: number, value: T, depth = 0): T { - if (writesIn(s)) return replaceIn(s[i], value, depth); + // A whole write of an element of an array of one `sliceIn` or `sliceOfPlace` made lands in the object there. + if (ONE.has(s)) return replaceIn(s[i], value, depth); const old = s[i]; s[i] = value; return old; @@ -1067,75 +1060,10 @@ export function sliceReplace(s: T[], i: number, value: T, dept * as `sliceReplace` copies, as the other's slot would otherwise take that object itself. */ export function sliceSwapAcross(a: T[], i: number, b: T[], j: number, depth = 0): void { - if (writesIn(b)) [a, i, b, j] = [b, j, a, i]; + if (ONE.has(b)) [a, i, b, j] = [b, j, a, i]; b[j] = sliceReplace(a, i, b[j], depth); } -/** What an `arrayView` answers to its own `View` by. */ -const VIEW = /* @__PURE__ */ Symbol("view"); - -/** An `arrayView`'s traps: of `length` elements of `s` from `start`. */ -class View implements ProxyHandler { - s: { [index: number]: T }; - start: number; - readonly length: number; - - constructor(s: { [index: number]: T }, start: number, length: number) { - this.s = s; - this.start = start; - this.length = length; - } - - /** The traps of a view of `length` of these elements from `start`. */ - part(start: number, length: number): View { - return new View(this.s, this.start + start, length); - } - - /** Element `i` of `s`. */ - item(i: number): T { - return this.s[i]; - } - - /** A write of element `i` of `s`. */ - put(i: number, value: T): void { - this.s[i] = value; - } - - /** Where in `s` the element `key` names is, or -1 if it names none. */ - at(key: string | symbol): number { - if (typeof key !== "string") return -1; - const i = Number(key); - return Number.isInteger(i) && i >= 0 && i < this.length && String(i) === key ? this.start + i : -1; - } - - get(target: T[], key: string | symbol): unknown { - if (key === VIEW) return this; - const i = this.at(key); - return i < 0 ? Reflect.get(target, key) : this.item(i); - } - - set(target: T[], key: string | symbol, value: T): boolean { - const i = this.at(key); - if (i < 0) return Reflect.set(target, key, value); - this.put(i, value); - return true; - } - - has(target: T[], key: string | symbol): boolean { - return this.at(key) >= 0 || Reflect.has(target, key); - } - - ownKeys(target: T[]): (string | symbol)[] { - return [...Array.from({ length: this.length }, (_, i) => String(i)), ...Reflect.ownKeys(target)]; - } - - getOwnPropertyDescriptor(target: T[], key: string | symbol): PropertyDescriptor | undefined { - const i = this.at(key); - if (i < 0) return Reflect.getOwnPropertyDescriptor(target, key); - return { value: this.item(i), writable: true, enumerable: true, configurable: true }; - } -} - /** * `op` of the elements of `s`, which it reads before writes that may overwrite them, as a * JS array: the storage itself where `s` is all of it, or else a copy, written back after. @@ -1285,11 +1213,16 @@ function arrayRefSet(s: ArrayRef, value: unknown): void { /** * The array `s` as a `[T; N]` of its own: a copy of its elements, and of the arrays it holds at * any depth, but not of the objects its elements are, which a write of it moves, unless - * `copy` copies them. + * `copy` copies them. `objectCopy`, of an object a write lands in, copies only where one does, + * in an array of one `sliceIn` or `sliceOfPlace` made, as a write elsewhere puts another + * object in the element's place and leaves the old one, such as a pinned `Box`, where it is. */ function arrayRefCopy(s: S, copy?: ElemCopy): LentArray { if (s instanceof ByteSlice) return byteSliceToArray(s) as LentArray; - if (s instanceof Slice) return sliceToArray(s, copy as ((value: unknown) => unknown) | undefined) as LentArray; + if (s instanceof Slice) { + const each = copy === objectCopy && !ONE.has(s.data) ? undefined : copy; + return sliceToArray(s, each as ((value: unknown) => unknown) | undefined) as LentArray; + } return arraySliceCopy(s as ArraySlice, copy) as LentArray; } @@ -2786,32 +2719,70 @@ export function roomPast(array: object, end: number): Room | undefined { return room; } -/** The traps of a view of a `Vec`'s storage, its items and then its room, from `start`. */ -class RoomView extends View { +/** What a `Vec`'s view of its storage and room answers to its own traps by. */ +const VIEW = /* @__PURE__ */ Symbol("view"); + +/** The items of the `Vec` whose storage and room `s` is a view of, if it is one. */ +function roomItems(s: object): { [index: number]: T } | undefined { + return (s as { [VIEW]?: RoomView })[VIEW]?.s; +} + +/** The traps of a view of the first `length` elements of a `Vec`'s storage: its items, `s`, and then its room. */ +class RoomView implements ProxyHandler { readonly room: Room; + readonly s: T[]; + readonly length: number; - constructor(room: Room, items: T[], start: number, length: number) { - super(items, start, length); + constructor(room: Room, s: T[], length: number) { this.room = room; + this.s = s; + this.length = length; + } + + /** Element `i`, of the items or the room. */ + item(i: number): T { + return i < this.s.length ? this.s[i] : this.room.get(i); } - override part(start: number, length: number): RoomView { - return new RoomView(this.room, this.s as T[], this.start + start, length); + /** Where the element `key` names is, or -1 if it names none. */ + at(key: string | symbol): number { + if (typeof key !== "string") return -1; + const i = Number(key); + return Number.isInteger(i) && i >= 0 && i < this.length && String(i) === key ? i : -1; } - override item(i: number): T { - return i < (this.s as T[]).length ? this.s[i] : this.room.get(i); + get(target: T[], key: string | symbol): unknown { + if (key === VIEW) return this; + const i = this.at(key); + return i < 0 ? Reflect.get(target, key) : this.item(i); } - override put(i: number, value: T): void { - if (i < (this.s as T[]).length) this.s[i] = value; + set(target: T[], key: string | symbol, value: T): boolean { + const i = this.at(key); + if (i < 0) return Reflect.set(target, key, value); + if (i < this.s.length) this.s[i] = value; else this.room.set(i, value); + return true; + } + + has(target: T[], key: string | symbol): boolean { + return this.at(key) >= 0 || Reflect.has(target, key); + } + + ownKeys(target: T[]): (string | symbol)[] { + return [...Array.from({ length: this.length }, (_, i) => String(i)), ...Reflect.ownKeys(target)]; + } + + getOwnPropertyDescriptor(target: T[], key: string | symbol): PropertyDescriptor | undefined { + const i = this.at(key); + if (i < 0) return Reflect.getOwnPropertyDescriptor(target, key); + return { value: this.item(i), writable: true, enumerable: true, configurable: true }; } } /** The first `end` elements of the allocation `room` is past, its items and then itself, as a JS array read and written where they are. */ function roomView(room: Room, end: number): T[] { - return new Proxy(new Array(end), new RoomView(room, room.items, 0, end)); + return new Proxy(new Array(end), new RoomView(room, room.items, end)); } /** `Vec::as_ptr` and `as_mut_ptr` of `size`-byte elements: the pointer to its first, which reaches its room. */ diff --git a/ts/runtime/rs/task.ts b/ts/runtime/rs/task.ts index 019616f4e..772d922b0 100644 --- a/ts/runtime/rs/task.ts +++ b/ts/runtime/rs/task.ts @@ -4,7 +4,7 @@ // A value whose drop JS can observe has `[Symbol.dispose]`, which runs its `Drop` impl // and drops its fields. `None` is `undefined`, which drops as nothing. -import { Abort, arrayAssign, type ByteSlice, type ArrayRef, type LentArray, type ElemCopy, ArraySlice, arraySliceItems, arraySliceCopy, arraySliceSet, type CloneFrom, cloneOver, type Debug, type DebugStruct, debugStructField, debugStructFinish, debugStructFinishNonExhaustive, debugTupleField, debugTupleFinish, Err, type FmtResult, type Formatter, fmtBool, fmtDebugStruct, fmtDebugTuple, fmtDebugTupleFields, fmtPad, fmtStr, type None, NULL, objectCopy, OK, Ok, Panic, panic, type Place, place, ptrErase, ptrHome, ptrNowhere, ptrWrite, type Result, Slice, stringAsBytes, type Vec, assertFailed, fmtOwned } from "../rs.ts"; +import { Abort, arrayAssign, type ByteSlice, type ArrayRef, type LentArray, type ElemCopy, ArraySlice, arraySliceItems, arraySliceCopy, arraySliceSet, type CloneFrom, cloneOver, type Debug, type DebugStruct, debugStructField, debugStructFinish, debugStructFinishNonExhaustive, debugTupleField, debugTupleFinish, Err, type FmtResult, type Formatter, fmtBool, fmtDebugStruct, fmtDebugTuple, fmtDebugTupleFields, fmtPad, fmtStr, type None, NULL, objectCopy, OK, Ok, Panic, panic, type Place, place, ptrErase, ptrHome, ptrNowhere, ptrWrite, type Result, Slice, sliceSet, sliceToArray, stringAsBytes, type Vec, assertFailed, fmtOwned } from "../rs.ts"; import type { Hasher } from "./hash.ts"; import type { Location } from "./location.ts"; @@ -912,12 +912,49 @@ export function cellOfPlace(p: Place): Cell { return p as Cell; } +/** + * A cell `Cell::from_mut` or `UnsafeCell::from_mut` makes of a `&mut [T; N]`, the slice `s`: + * a read is a copy of the array, a write lands where `s` holds it, and a pointer to it is `s`. + */ +class ArrayCell implements Place { + readonly s: S; + readonly #read: () => A; + readonly #write: (value: A) => void; + + constructor(s: S, read: () => A, write: (value: A) => void) { + this.s = s; + this.#read = read; + this.#write = write; + } + + get v(): A { + return this.#read(); + } + + set v(value: A) { + this.#write(value); + } +} + +/** `Cell::from_mut` or `UnsafeCell::from_mut` of a `&mut [T; N]`, which is `s`. */ +export function cellOfSlice(s: Slice): Cell { + return cellOfPlace(new ArrayCell(s, () => sliceToArray(s), (value: T[]) => sliceSet(s, value))); +} + /** * `Cell::from_mut` of a `&mut [[T; N]; M]`, which is the arrays `r`: a read is a copy of * them, each element copied by `copy`, and a write lands where `r` holds them. */ export function cellOfArraySlice(r: ArraySlice, copy?: ElemCopy): Cell[]> { - return cellOfPlace(place(() => arraySliceCopy(r, copy), (value) => arraySliceSet(r, value))); + return cellOfPlace(new ArrayCell(r, () => arraySliceCopy(r, copy), (value: LentArray[]) => arraySliceSet(r, value))); +} + +/** + * The pointer to the array a cell of one, `c`, holds, the slice of it `from` makes: the slice + * `Cell::from_mut` made it of, or else the slice of all of the array. + */ +export function cellArray(c: Cell, from: (array: A) => S): S { + return c instanceof ArrayCell ? (c.s as S) : from(c.v); } /** diff --git a/ts/src/census.rs b/ts/src/census.rs index 958b34085..4c2ea8b3e 100644 --- a/ts/src/census.rs +++ b/ts/src/census.rs @@ -144,6 +144,7 @@ const VERBATIM: &[&str] = &[ "?", "Arc", "Binary", + "Box::from_raw", "Buf::copy_to_bytes", "BufMut::put", "BytesMut", @@ -181,6 +182,7 @@ const VERBATIM: &[&str] = &[ "Vec::splice", "alloc", "array::from_ref", + "as_chunks", "async", "async fn", "become", diff --git a/ts/src/lower/lend.rs b/ts/src/lower/lend.rs index f629db886..2687dbade 100644 --- a/ts/src/lower/lend.rs +++ b/ts/src/lower/lend.rs @@ -77,6 +77,10 @@ pub fn plan<'tcx>(t: &Translator<'_, 'tcx>, def_id: DefId, args: GenericArgsRef< | ("ToOwned", "clone_into") | ("raw" | "array" | "Cell" | "UnsafeCell" | "ptr", "from_mut") | ("Option", "get_or_insert" | "get_or_insert_with" | "get_or_insert_default" | "insert") => true, + // A reference to an array a pointer or a cell points at, which is the slice the pointer is. + ("ptr" | "NonNull", "as_ref" | "as_mut") + | ("UnsafeCell", "get_mut" | "as_ref_unchecked" | "as_mut_unchecked") + | ("Cell", "get_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. @@ -335,10 +339,10 @@ pub fn lend<'tcx>(b: &mut Body<'_, '_, 'tcx>, generic: Ty<'tcx>, ty: Ty<'tcx>, v /// `value`, a `ty` translated code gives std's mapping as an input whose type in std's /// generic code is `generic`, as the mapping reads it: each `&[T; N]` where it takes a /// `&T`, which it reads, copies, and writes through as the array: the `rs.byteSliceView` -/// of an `rs.ByteSlice`, or the `rs.sliceView` of an `rs.Slice` lent mutably, which share -/// the elements for as long as the reference lives, so whatever the mapping keeps of it -/// reads and writes where the reference does, or else the `rs.sliceItems`, which reads -/// them faster than a view where the slice is part of an array. +/// of an `rs.ByteSlice`, which shares the bytes for as long as the reference lives, so +/// whatever the mapping keeps of it reads and writes where the reference does, or else the +/// `rs.sliceItems` of a shared one, which nothing writes through. A mutable one of other +/// elements, which no JS array shares, is refused. pub fn give<'tcx>(b: &mut Body<'_, '_, 'tcx>, generic: Ty<'tcx>, ty: Ty<'tcx>, value: Expr, span: Span) -> Expr { cross(b, generic, ty, value, Way::Given, span) } @@ -395,7 +399,6 @@ fn cross<'tcx>(b: &mut Body<'_, '_, 'tcx>, generic: Ty<'tcx>, ty: Ty<'tcx>, valu // The slice of the elements a slice was read as is that slice. Expr::Rs(f) if f == "sliceFrom" => super::library::slice_from(value), Expr::Rs(f) if f == "sliceItems" => super::library::slice_items(value), - Expr::Rs(f) if f == "sliceView" => super::library::slice_view(value), f => f.call(vec![value]), } } @@ -405,24 +408,27 @@ fn cross_fn<'tcx>(b: &mut Body<'_, '_, 'tcx>, generic: Ty<'tcx>, ty: Ty<'tcx>, w if let ty::Ref(_, inner, mutability) = ty.kind() && let ty::Array(elem, _) = inner.kind() { + // Only bytes have a JS array that is part of another, a `Uint8Array` view, so a mapping + // can't write through any other part of an array as an array. + if way == Way::Given && *mutability == ty::Mutability::Mut && !super::byte(*elem) { + return b.err( + span, + format!("giving std a `{ty}` to write through as an array, which is not supported yet"), + ); + } // An array slice, each array lent as its own `From` lends it, and given as copies, which a `&` reads. if elem.is_array() { - return match (way, mutability) { - (Way::Lent, _) => super::array_fn(*inner, "From"), - (Way::Given, ty::Mutability::Not) => Expr::Rs("arraySliceItems".into()), - (Way::Given, ty::Mutability::Mut) => b.err( - span, - format!("giving std a `{ty}` to write through as an array, which is not supported yet"), - ), + return match way { + Way::Lent => super::array_fn(*inner, "From"), + Way::Given => Expr::Rs("arraySliceItems".into()), }; } return Expr::Rs( - match (way, super::byte(*elem), mutability) { - (Way::Lent, true, _) => "byteSliceFrom", - (Way::Given, true, _) => "byteSliceView", - (Way::Lent, false, _) => "sliceFrom", - (Way::Given, false, ty::Mutability::Mut) => "sliceView", - (Way::Given, false, ty::Mutability::Not) => "sliceItems", + match (way, super::byte(*elem)) { + (Way::Lent, true) => "byteSliceFrom", + (Way::Given, true) => "byteSliceView", + (Way::Lent, false) => "sliceFrom", + (Way::Given, false) => "sliceItems", } .into(), ); diff --git a/ts/src/lower/library.rs b/ts/src/lower/library.rs index fd49bacc6..171f59f6e 100644 --- a/ts/src/lower/library.rs +++ b/ts/src/lower/library.rs @@ -4272,12 +4272,6 @@ pub fn items_of(s: Expr, elem: Ty<'_>) -> Expr { } } -/// The array of `s`, an `rs.Slice`, as `rs.sliceView` writes through it: all of an array is -/// the array. -pub fn slice_view(s: Expr) -> Expr { - array_of(s, "sliceView") -} - /// `rs.{read}` of `s`, an `rs.Slice`: the array of an `rs.sliceFrom`. fn array_of(s: Expr, read: &str) -> Expr { match s { @@ -4293,12 +4287,10 @@ fn array_of(s: Expr, read: &str) -> Expr { } /// All of `items`, a JS array, as an `rs.Slice`, as `rs.sliceFrom` makes one: the elements -/// `rs.sliceItems` or `rs.sliceView` read of a slice are that slice. +/// `rs.sliceItems` reads of a slice are that slice. pub fn slice_from(items: Expr) -> Expr { match items { - Expr::Call(f, mut args) - if matches!(&*f, Expr::Rs(n) if n == "sliceItems" || n == "sliceView") && args.len() == 1 => - { + Expr::Call(f, mut args) if matches!(&*f, Expr::Rs(n) if n == "sliceItems") && args.len() == 1 => { args.pop().unwrap() } items => Expr::rs("sliceFrom", vec![items]), diff --git a/ts/src/lower/mir/call.rs b/ts/src/lower/mir/call.rs index 63d77fda8..fa8fcd6a9 100644 --- a/ts/src/lower/mir/call.rs +++ b/ts/src/lower/mir/call.rs @@ -1659,14 +1659,6 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { if let ty::Array(elem, len) = ty.kind() && (!cell || elem.is_array()) { - if owner == "UnsafeCell" { - return Some(self.err( - span, - format!( - "`UnsafeCell::from_mut` of `{ty}`, an array of arrays, which a cell of it reads a copy of, so a write through its pointer would land in the copy" - ), - )); - } let slice = self.operand(op, span, out); if cell { let copy = self.b.t.elem_copy(ty, span); @@ -1690,9 +1682,23 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { ), )); } + // The bytes a `&mut [u8; N]` views, or a cell of the slice a `&mut` to another array is, + // where its writes land. if self.in_array(deref) { + let inner = self.b.t.uninit_inner(ty); + if crate::lower::byte_array(inner) { + let slice = self.place_expr(deref, span, out); + return Some(of_object(Expr::rs("byteSliceView", vec![slice]))); + } + if !cell || crate::lower::array_slice::of_arrays(inner) { + let path = if owner == "raw" { "slice" } else { owner }; + return Some(self.err( + span, + format!("`{path}::from_mut` of `{ty}`, an array a `MaybeUninit` holds, which is not supported yet"), + )); + } let slice = self.place_expr(deref, span, out); - return Some(of_object(self.b.t.array_rs(ty, "View").call(vec![slice]))); + return Some(Expr::rs("cellOfSlice", vec![slice])); } // A cell of an object is of it wherever it is, as its place may be one a write lands // in, such as an element of a slice of one. @@ -2031,9 +2037,9 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { } Some(p) => { let slice = self.borrowed_slice(place.0, p, span, out); - let mut made = vec![Expr::rs("sliceView", vec![slice]), value]; + let mut made = vec![slice, value]; made.extend(self.b.t.copy_depth(ty)); - Expr::rs("replaceIn", made) + Expr::rs("sliceReplaceAll", made) } None => { let mut made = vec![place.0, value]; diff --git a/ts/src/lower/mir/rvalue.rs b/ts/src/lower/mir/rvalue.rs index 91887cf7d..17cff3689 100644 --- a/ts/src/lower/mir/rvalue.rs +++ b/ts/src/lower/mir/rvalue.rs @@ -56,23 +56,15 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { } } let value = self.place_expr(*place, span, out); - // A borrow of an array is a slice of all of it, sharing its elements. A shared one - // of a `MaybeUninit` of one through a raw pointer is the array of the pointer's - // elements: a view of bytes, and else the array where the slice is all of it. + // A borrow of an array is a slice of all of it, sharing its elements. One of a + // `MaybeUninit` of one through a raw pointer is the array: a view of bytes, and + // else refused, as the pointer may point into part of an array, which has no JS + // array of its own, so a copy would lose writes and differ in address. let pointee = place.ty(&self.mir.local_decls, tcx).ty; match (pointee.is_array(), self.in_array(*place)) { (true, false) => crate::lower::array_slice(self.b.t.uninit_inner(pointee), value), (false, true) if self.in_bytes(*place) => Expr::rs("byteSliceView", vec![value]), - (false, true) => match self.b.t.uninit_inner(pointee).kind() { - // Part of an array, or arrays `as_chunks_mut` splits from one slice, has - // no JS array of its own, so a write through a copy of it would be lost. - ty::Array(..) if matches!(kind, mir::BorrowKind::Mut { .. }) => self.err( - span, - format!("a mutable reborrow of `{pointee}` through a raw pointer, which may point into part of an array with no JS array of its own, which is not supported yet"), - ), - ty::Array(elem, _) => crate::lower::library::items_of(value, *elem), - _ => crate::lower::library::slice_items(value), - }, + (false, true) => self.err(span, crate::lower::pointer::uninit_reborrow(pointee)), _ => value, } } diff --git a/ts/src/lower/pointer.rs b/ts/src/lower/pointer.rs index 4c3fc6dbd..a31f5a3e9 100644 --- a/ts/src/lower/pointer.rs +++ b/ts/src/lower/pointer.rs @@ -580,14 +580,17 @@ pub fn call<'tcx>( ty::Array(elem, _) => super::slice_items_from(e, *elem), _ => super::library::slice_from(e), }; - // The arrays of an array of arrays have no JS array to write through. - let to_reference = |b: &mut Body<'_, '_, 'tcx>, e: Expr| match b.t.uninit_inner(pointee()) { - ty if super::byte_array(ty) => Expr::rs("byteSliceView", vec![e]), - ty if super::array_slice::of_arrays(ty) => b.err( - span, - format!("a reference to `{ty}` from a raw pointer, which is not supported yet"), - ), - _ => super::library::slice_view(e), + // A reference to the array a pointer points at: the slice the pointer is, or for one a + // `MaybeUninit` or `ManuallyDrop` holds, whose reference is the array, as a reborrow of + // `*p` makes it: a view of bytes, and else refused. + let to_reference = |b: &mut Body<'_, '_, 'tcx>, p: Expr| { + let ty = pointee(); + let inner = b.t.uninit_inner(ty); + match inner { + _ if inner == ty => p, + _ if super::byte_array(inner) => Expr::rs("byteSliceView", vec![p]), + _ => b.err(span, uninit_reborrow(ty)), + } }; // A raw pointer to a slice, from a reference to one, and the slice a read through it // makes, shared if nothing writes through it. @@ -664,7 +667,10 @@ pub fn call<'tcx>( ("NonNull", "as_ref" | "as_mut") if kind(b, pointee()) == Some(Pointee::Slice) => { deref(pointee(), arg(), name == "as_ref") } - ("NonNull", "as_mut") if array(b, pointee()) => to_reference(b, arg()), + ("NonNull", "as_mut") if array(b, pointee()) => { + let p = arg(); + to_reference(b, p) + } // A `&mut` to a `MaybeUninit` of a cell of a value JS copies is the place the cell is // kept in, but one to the cell is the cell. ("MaybeUninit", "assume_init_mut") @@ -740,7 +746,16 @@ pub fn call<'tcx>( let shared = name == "as_ref" && kind(b, pointee()) == Some(super::pointer::Pointee::Place); let (some, none) = match shared { true => (p.clone().member("v"), b.t.none(pointee())), - false if array(b, pointee()) => (to_reference(b, p.clone()), Expr::undefined()), + // The `None` of an `Option` of the reference, which may be `rs.None` where the + // reference is the array a `MaybeUninit` holds. + false if array(b, pointee()) => { + let lent = b.t.sig(call.def_id, gargs).output(); + let none = match lent.kind() { + ty::Adt(_, args) => b.t.none(args.type_at(0)), + _ => Expr::undefined(), + }; + (to_reference(b, p.clone()), none) + } false => (p.clone(), Expr::undefined()), }; Expr::Cond( @@ -751,7 +766,10 @@ pub fn call<'tcx>( } ("NonNull", "as_ref") | ("MaybeUninit", "assume_init_ref") => match kind(b, pointee()) { Some(Pointee::Place) if owner == "NonNull" => arg().member("v"), - Some(Pointee::Array) if owner == "NonNull" => to_reference(b, arg()), + Some(Pointee::Array) if owner == "NonNull" => { + let p = arg(); + to_reference(b, p) + } _ => arg(), }, // An `rs.Arc` is its allocation, which has one place of its value: the pointer to a @@ -823,7 +841,29 @@ pub fn call<'tcx>( ("Box", "from_raw") => match kind(b, pointee()) { Some(Pointee::Slice) => deref(pointee(), arg(), false), Some(Pointee::Place) => arg().member("v"), - Some(Pointee::Array) => to_reference(b, arg()), + // A box of an array is the array, all of which `into_raw` pointed at. One of no + // bytes owns no allocation, so any pointer of any length makes one: a new array, as + // a dangling pointer's is. Arrays `as_chunks` split from one flat array have no + // array of their own to box. + Some(Pointee::Array) => match b.t.uninit_inner(pointee()) { + ty if super::byte_array(ty) => Expr::rs("byteSliceView", vec![arg()]), + ty if b.t.zero_sized(ty) => match ty.kind() { + ty::Array(elem, len) if b.t.empty(*elem) || len.try_to_target_usize(b.t.tcx) == Some(0) => { + b.t.uninit(pointee(), span) + } + _ => b.err( + span, + format!("`Box::from_raw` of `{ty}`, a value of no bytes made of more than structs and tuples"), + ), + }, + ty if super::array_slice::of_arrays(ty) => b.err( + span, + format!( + "`Box::from_raw` of `{ty}`, which may be arrays `as_chunks` split from one flat array, which is not supported yet" + ), + ), + _ => Expr::rs("boxArrayFromRaw", vec![arg()]), + }, _ => arg(), }, ("ptr", "read" | "read_unaligned" | "read_volatile") => { @@ -988,6 +1028,14 @@ pub fn call<'tcx>( } // What `get` points at, lent as `get_mut` lends it. ("UnsafeCell" | "Cell", "get_mut") | ("UnsafeCell", "as_mut_unchecked") if b.t.needs_place(pointee()) => arg(), + // The pointer `get` gives to an array is the reference to it, which `lend` leaves as it + // is; one a `MaybeUninit` holds is the array, which the cell holds. + ("UnsafeCell", "get_mut" | "as_ref_unchecked" | "as_mut_unchecked") | ("Cell", "get_mut") + if pointee().is_array() => + { + let cell = arg(); + cell_pointer(b, cell, pointee()) + } ("UnsafeCell", "get_mut" | "as_ref_unchecked" | "as_mut_unchecked" | "into_inner") | ("Cell", "get_mut") => { arg().member("v") } @@ -1303,8 +1351,13 @@ pub(super) fn cell_pointer<'tcx>(b: &Body<'_, '_, 'tcx>, cell: Expr, ty: Ty<'tcx if pointee == Pointee::Place { return cell; } + let inner = b.t.uninit_inner(ty); + if pointee == Pointee::Array && !super::byte_array(inner) { + // The slice `Cell::from_mut` made the cell of, or else of all of the array it holds. + return Expr::rs("cellArray", vec![cell, super::array_fn(inner, "From")]); + } let held = cell.member("v"); - match (pointee, b.t.uninit_inner(ty).kind()) { + match (pointee, inner.kind()) { (Pointee::Array, ty::Array(elem, _)) => super::slice_items_from(held, *elem), (Pointee::Slice, _) if slice_of_bytes(ty) => Expr::rs("rawByteSliceOf", vec![held]), (Pointee::Slice, _) if slice_of_arrays(ty) => Expr::rs("rawArraySliceOf", vec![held]), @@ -1351,19 +1404,21 @@ pub(super) fn replace<'tcx>( /// What `p`, a pointer to `ty`, points at, as a value of its own that a whole write there /// after leaves as it was. The write lands in the object or array a pointer is, so one is -/// copied one object deep, an array's elements to the depth `objectCopy` copies them. One +/// copied one object deep, an array's elements to the depth `objectCopy` copies them, and an +/// array of arrays' as [`super::Translator::elem_copy`] says. One /// a pointer is the place of is read as it is, keeping a `Box`'s allocation, as its write /// puts another in the place. fn copied_out<'tcx>(b: &mut Body<'_, '_, 'tcx>, p: Expr, ty: Ty<'tcx>, span: Span, out: &mut Vec) -> Expr { match b.t.pointee(ty) { _ if b.t.zero_sized(ty) || b.t.keeps_cells(ty) => read(b, p, ty, span, out), Pointee::Object => Expr::rs("objectCopy", vec![p]), - Pointee::Array - if !super::byte_array(b.t.uninit_inner(ty)) && !super::array_slice::of_arrays(b.t.uninit_inner(ty)) => - { + Pointee::Array if super::array_slice::of_arrays(b.t.uninit_inner(ty)) => { + let copy = b.t.elem_copy(b.t.uninit_inner(ty), span); + Expr::rs("arraySliceCopy", std::iter::once(p).chain(copy).collect()) + } + Pointee::Array if !super::byte_array(b.t.uninit_inner(ty)) => { let depth = b.t.copy_depth(b.t.uninit_inner(ty)); - let view = super::library::slice_view(p); - Expr::rs("objectCopy", std::iter::once(view).chain(depth).collect()) + Expr::rs("sliceCopy", std::iter::once(p).chain(depth).collect()) } _ => read(b, p, ty, span, out), } @@ -1561,6 +1616,15 @@ fn object_field<'tcx>(b: &mut Body<'_, '_, 'tcx>, object: Expr, ty: Ty<'tcx>, i: } } +/// Why a reborrow through a raw pointer of `ty`, an array a `MaybeUninit` or `ManuallyDrop` +/// holds of other than bytes, is refused: its reference is the array, which part of an array +/// has none of its own, so a shared one would be a copy at another address. +pub fn uninit_reborrow(ty: Ty<'_>) -> String { + format!( + "a reborrow of `{ty}` through a raw pointer, which may point into part of an array with no JS array of its own to lend, which is not supported yet" + ) +} + /// Whether `ty` is `[u8]`, one of `MaybeUninit`, or an `UninitSlice`, whose slices are /// `rs.ByteSlice`s. pub fn slice_of_bytes(ty: Ty<'_>) -> bool { diff --git a/ts/src/lower/task.rs b/ts/src/lower/task.rs index 8b6197e5c..8faf39496 100644 --- a/ts/src/lower/task.rs +++ b/ts/src/lower/task.rs @@ -594,12 +594,9 @@ fn cell<'tcx>( let span = call.span; let ty = call.args.type_at(0); // A pointer `as_ptr` gave to an object or an array is it, so a write lands in it, as it - // does in each cell a value keeps. A cell of arrays of arrays may be `Cell::from_mut`'s, - // which reads a copy of them, so it is written whole. - let arrays = super::array_slice::of_arrays(b.t.uninit_inner(ty)); - let in_place = (matches!(b.t.pointee(ty), Pointee::Object | Pointee::Array) || b.t.keeps_cells(ty)) - && !b.t.zero_sized(ty) - && !arrays; + // does in each cell a value keeps. + let in_place = + (matches!(b.t.pointee(ty), Pointee::Object | Pointee::Array) || b.t.keeps_cells(ty)) && !b.t.zero_sized(ty); let default = |b: &mut Body<'_, '_, 'tcx>, out: &mut Vec| { let f = super::collections::trait_fn(tcx, "Default", "default"); b.call_def(f, tcx.mk_args(&[ty.into()]), Vec::new(), span, out)