Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions quest/m3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ generic std gap is planned here even when moq never calls it.
- [Type errors at the Rust that made them](/quest/m3/ts-span-precision.md) - a `tsc` error on output names the tail expression or call argument that made it
- [An empty iterator of mutable references](/quest/m3/ts-empty-places.md) - `iter::empty::<&mut T>()` given to `zip` or `chain` translates
- [An Option of numbers in the result slot](/quest/m3/ts-option-slot.md) - `varint_opt`'s `Option` comes back through the slot with no object per call
- [Fresh writes through a zip, a copy, and a repeat](/quest/m3/ts-fresh-shapes.md) - zipping a `Vec<[T; N]>`, reading a `T` out of `Zip::next`, and `copied` or `vec![x; n]` over a `Copy` type translate
30 changes: 30 additions & 0 deletions quest/m3/ts-fresh-shapes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# [M] Fresh writes through a zip, a copy, and a repeat

## Goal

[rust2-ts](/ts/README.md) translates three shapes it refuses for concrete types and type
parameters alike, proven by differential tests against native Rust:

- zipping a slot with a `Vec<[T; N]>`, as `[u8; N]`;
- reading a `T` back out of `Zip::next`'s result;
- `iter().copied()` and `vec![x; n]` over a `Copy` type, a crate's own or a `T: Copy`.

## Plan

Found by [#394](https://github.com/moq-dev/rust2/pull/394), which made a whole write into
fresh memory count as fresh in a function generic over a type. These three stay refused for
reasons that have nothing to do with type parameters:

- `vec::IntoIter` points at a type the slot holds in place, so zipping with it refuses.
- Reading a `T` out of `Zip::next`'s result makes it a holder. A concrete control
(`Vec<Option<u8>>`) is refused as well.
- `Copy`'s supertrait `Clone` selects a parameter candidate, so `copied` and `vec![x; n]`
count as running the crate's `Clone`. The two differ: `copied` copies and calls no
`clone`, while `vec![x; n]` calls `clone` `n - 1` times, and a `Copy` type's hand-written
`Clone` may have effects or panic. Treat `copied` as running no crate code; keep
`vec![x; n]` calling the crate's `clone`, judged fresh only where that `clone` writes
nothing the slot holds. Cover both with differential tests whose `Clone` logs and panics.

Reproduce each first and fix the one that is a single cause before the others.

Public API: the translator's output.