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: 0 additions & 1 deletion quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ are folded into the [exporter's](/quest/m1/ffi-export/README.md). The
## Required

- [Waiting: publish the UniFFI fork](/quest/m1/uniffi-release.md) - the fork publishes to crates.io under `rust2-*` names, once the maintainer decides it should
- [Vec views of the right type](/quest/m1/ts-vec-view.md) - rust2-ts never translates a `Vec` of non-bytes as bytes, and the exporter's pin bump unblocks
- [Strings from UTF-8 bytes](/quest/m1/ts-utf8.md) - `str::from_utf8` translates, so the translator follows moq past its owned `Path`
- [Exporter](/quest/m1/ffi-export/README.md) - moq's bindings exported from its crates' `pub` API, replacing the fork
- [Land main through quest land](/quest/m1/land.md) - every queued PR lands as one tested batch through the shared gate
2 changes: 1 addition & 1 deletion quest/m1/ts-utf8.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ past [moq-dev/moq#6843](https://github.com/moq-dev/moq/pull/6843), whose decoder

Decided with the maintainer on 2026-10-27: the exporter and the translator share one moq
pin, so [the exporter's pin bump](https://github.com/kixelated/rust2/pull/144) merges once
this and [the `Vec` view fix](/quest/m1/ts-vec-view.md) pass at its revision.
this passes at its revision.

- `TextDecoder` with `fatal` rejects what std rejects, but the error position must be std's
`valid_up_to` and `error_len`, so check its edge cases (truncated sequences, surrogates,
Expand Down
17 changes: 0 additions & 17 deletions quest/m1/ts-vec-view.md

This file was deleted.

32 changes: 29 additions & 3 deletions ts/fixtures/lang/expected/collections.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Generated by rust2-ts. Do not edit.

import * as rt from "./rt.ts";
import { copy$Bumped, copy$Tally, copy$u8_Tally, copy$u8_str, copy$u8_u16, copy$u8_u16s, copy$u8_u8, copy$u8_u8s } from "./lib.ts";
import { copy$Bumped, copy$Tally, copy$Wrap_u8, copy$u8_Tally, copy$u8_str, copy$u8_u16, copy$u8_u16s, copy$u8_u8, copy$u8_u8s } from "./lib.ts";
import * as Clash from "./collections.Clash.ts";
import * as Cloned from "./collections.Cloned.ts";
import * as Dir from "./collections.Dir.ts";
Expand All @@ -12,6 +12,7 @@ import * as Pair from "./collections.Pair.ts";
import * as Rank from "./collections.Rank.ts";
import * as Tally from "./collections.Tally.ts";
import { unwrapOr$Option_u16, unwrapOr$Option_u8, mapOr$Option_Nibble_u8_sets_closure4, mapOr$Option_Rank_Tally_u8_hash_maps_closure11, mapOr$Option_Tally_u8_hash_maps_closure10, mapOr$Option_u16_u8_hash_maps_closure0, mapOr$Option_u8_u8_u8_btree_maps_closure0, mapOr$Option_u8_u8_u8s_stores_closure2_closure0 } from "./core/option.ts";
import * as Wrap from "./generics.Wrap.ts";
import * as Bumped from "./iters.Bumped.ts";

/** A 64-bit key: small, or past 2^53, where it is no longer a JS number. */
Expand Down Expand Up @@ -958,15 +959,17 @@ export function vecs(data: rt.ByteSlice, out: rt.ByteVec): void {
} else {
name = "?";
}
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(rt.byteVecFrom(Uint8Array.of(a, b, 66))));
const bytes: rt.ByteVec = rt.byteVecFrom(Uint8Array.of(a, b, 66));
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(bytes));
const pairs: [rt.u8, rt.u16][] = copy$u8_u16s([[a, b as rt.u16] as [rt.u8, rt.u16]]).map(copy$u8_u16);
pairs.push([b, a as rt.u16] as [rt.u8, rt.u16]);
const at = rt.idx(pairs, 0);
pairs[at][0] = pairs[at][0] ^ 255;
for (const _39 of pairs) {
rt.byteVecPush(out, _39[0] ^ (_39[1] & 0xff));
}
rt.byteVecPush(out, [name, "x", name].length & 0xff);
const names: string[] = [name, "x", name];
rt.byteVecPush(out, names.length & 0xff);
const one: Cloned.Cloned[] = [{ depth: a, name: name }];
rt.byteVecPush(out, one[rt.idx(one, 0)].depth);
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(rt.byteVecOf(b, n)));
Expand Down Expand Up @@ -1013,6 +1016,29 @@ export function vecs(data: rt.ByteSlice, out: rt.ByteVec): void {
rt.iterExtendBytes(out, rt.iterMap(rt.iterChain(rt.iterSlice(bumps), rt.iterSlice(kept)), (o2: Bumped.Bumped): rt.u8 => {
return o2._0;
}));
const grown: rt.ByteVec = rt.byteVecFrom(rt.byteVecView(bytes));
const _169: rt.ByteSlice = rt.byteVecSlice(grown);
rt.idx(_169, 0);
_169.data[_169.start] = _169.data[_169.start] ^ 255;
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(grown));
const iterS2: rt.ByteVec[] = [bytes, rt.byteVecOf(b, n)];
for (const _187 of iterS2) {
rt.byteVecPush(out, _187.length & 0xff);
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(_187));
}
const wrapped: Wrap.Wrap<rt.u8>[] = rt.vecFromElem(new Wrap.Wrap({ value: a, count: b }), n, copy$Wrap_u8);
if (n > 0) {
const _199: Wrap.Wrap<rt.u8>[] = wrapped;
const _201: rt.usize = rt.usizeSub(n, 1);
rt.idx(_199, _201);
_199[_201].count = _199[_201].count ^ 255;
}
rt.iterExtendBytes(out, rt.iterMap(rt.iterSlice(wrapped), (w2: Wrap.Wrap<rt.u8>): rt.u8 => {
return w2.value ^ w2.count;
}));
rt.iterExtendBytes(out, rt.iterMap(rt.iterSlice(names), (s2: string): rt.u8 => {
return rt.stringLen(s2) & 0xff;
}));
}

/** Stores `p` by value in `v`. */
Expand Down
17 changes: 17 additions & 0 deletions ts/fixtures/lang/src/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::cmp::Ordering;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque, btree_map, hash_map};
use std::hash::{DefaultHasher, Hash, Hasher};

use crate::generics::Wrap;
use crate::iters::Bumped;

/// A key whose `Eq`, `Hash`, and `Ord` see only its low nibble, so two keys can be equal
Expand Down Expand Up @@ -742,6 +743,22 @@ pub fn vecs(data: &[u8], out: &mut Vec<u8>) {
out.extend_from_slice(&[pair.0, pair.1, listed[1].0, held.0]);
out.extend(repeated.iter().chain(&again).map(|t| t.1));
out.extend(bumps.iter().chain(&kept).map(|o| o.0));

// A `Vec`'s slice is bytes only when its own elements are bytes.
let mut grown = bytes.clone();
grown.as_mut_slice()[0] ^= 0xff;
out.extend_from_slice(grown.as_slice());
let nested = vec![bytes, vec![b; n]];
for v in nested.as_slice() {
out.push(v.len() as u8);
out.extend_from_slice(v);
}
let mut wrapped = vec![Wrap { value: a, count: b }; n];
if n > 0 {
wrapped.as_mut_slice()[n - 1].count ^= 0xff;
}
out.extend(wrapped.as_slice().iter().map(|w| w.value ^ w.count));
out.extend(names.as_slice().iter().map(|s| s.len() as u8));
}

/// A struct that is not `Copy` holding a `Copy` aggregate by value.
Expand Down
12 changes: 4 additions & 8 deletions ts/src/lower/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,8 +944,8 @@ fn mapping<'tcx>(
let ty = targ(gargs, 0);
let v = args.pop()?;
match ty.kind() {
ty::Adt(adt, _) => match Std::of(tcx, adt.did()) {
Some(Std::Vec) => vec_view(v, ty),
ty::Adt(adt, vargs) => match Std::of(tcx, adt.did()) {
Some(Std::Vec) => vec_view(v, vargs.type_at(0)),
Some(Std::String | Std::Box) => v,
Some(Std::Cow) if string(tcx, ty) => v,
_ => return None,
Expand Down Expand Up @@ -1222,12 +1222,8 @@ fn primitive(ty: Ty<'_>) -> bool {
matches!(ty.kind(), ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Char)
}

/// A `Vec`'s elements as a slice: an `rt.ByteSlice` of a byte vector, or the array itself.
pub fn vec_view(v: Expr, ty: Ty<'_>) -> Expr {
let elem = match ty.peel_refs().kind() {
ty::Adt(_, args) => args.type_at(0),
_ => ty,
};
/// A `Vec` of `elem`s as a slice: an `rt.ByteSlice` of a byte vector, or the array itself.
pub fn vec_view(v: Expr, elem: Ty<'_>) -> Expr {
match elem.kind() {
ty::Uint(ty::UintTy::U8) => Expr::rt("byteVecSlice", vec![v]),
_ => v,
Expand Down
2 changes: 1 addition & 1 deletion ts/src/lower/mir/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> {
// still held back.
let (start, end) = self.range_bounds(&args[1].node, index_ty, span, out)?;
let base = match container.kind() {
ty::Adt(..) => library::vec_view(base, container),
ty::Adt(..) => library::vec_view(base, elem_ty),
_ => base,
};
let base = self.path(base, "slice", out);
Expand Down