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
2 changes: 1 addition & 1 deletion quest/m0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ Urgent fixes to anything a consumer already depends on.
## Required

- [Checks at moq's cost](/quest/m0/checks/README.md) - `just ci` selects by the diff, builds warm, and runs the differential optimized, with a nightly full `just gate`
- [Translating moq-net panics on a dyn Buf](/quest/m0/ts-moq-dyn-panic.md) - `just ts moq` and `just ts bench` translate moq-net at the pin again
- [Gate moq-net's translation](/quest/m0/ts-moq-gate.md) - `just ci` translates moq-net at the pin, so a change that breaks it fails in the queue
19 changes: 0 additions & 19 deletions quest/m0/ts-moq-dyn-panic.md

This file was deleted.

22 changes: 22 additions & 0 deletions quest/m0/ts-moq-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# [S] Gate moq-net's translation

## Goal

A change that breaks moq-net's translation fails in the merge queue, not the next nightly:
`just ci` for a `ts` change translates moq-net at the pin and type-checks it, as
`just ts moq` does. Today only `nightly.yml` runs `just ts moq`, so
[moq-dev/rust2#519](https://github.com/moq-dev/rust2/pull/519) landed a panic on moq-net
that a bench run found hours later.

## Plan

`just ts check` already checks out the pin for the bench's type-check, so what this adds is
building moq-net's dependencies through the driver and translating it. Measure that in CPU,
cold and warm, against [the checks budget](/quest/m0/checks/README.md) before adding it;
if it costs too much, consider running it only for changes under `ts/src` or `ts/runtime`.

Public API: none.

## Related

- [Checks at moq's cost](/quest/m0/checks/README.md) - the gate's CPU budget this spends from
3 changes: 2 additions & 1 deletion ts/fixtures/stock/expected/buf.Leased.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Generated by rust2-ts. Do not edit.

import * as rt from "./rt.ts";
import type * as Buf from "./bytes/buf/buf_impl.Buf.ts";
import type * as TryGetError from "./bytes.TryGetError.ts";

/** A buffer of the crate's own over `Buf`, as moq's transports lend a stream's chunks. */
export type Leased =
| { pieces$Leased: () => rt.usize; remaining$Buf: () => rt.usize; chunk$Buf: () => rt.ByteSlice; advance$Buf: (a0: rt.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rt.ByteSlice) => void; getU8$Buf: () => rt.u8; getI8$Buf: () => rt.i8; getU16$Buf: () => rt.u16; getU16Le$Buf: () => rt.u16; getU16Ne$Buf: () => rt.u16; getI16$Buf: () => rt.i16; getI16Le$Buf: () => rt.i16; getI16Ne$Buf: () => rt.i16; getU32$Buf: () => rt.u32; getU32Le$Buf: () => rt.u32; getU32Ne$Buf: () => rt.u32; getI32$Buf: () => rt.i32; getI32Le$Buf: () => rt.i32; getI32Ne$Buf: () => rt.i32; getU64$Buf: () => rt.u64; getU64Le$Buf: () => rt.u64; getU64Ne$Buf: () => rt.u64; getI64$Buf: () => rt.i64; getI64Le$Buf: () => rt.i64; getI64Ne$Buf: () => rt.i64; getU128$Buf: () => rt.u128; getU128Le$Buf: () => rt.u128; getU128Ne$Buf: () => rt.u128; getI128$Buf: () => rt.i128; getI128Le$Buf: () => rt.i128; getI128Ne$Buf: () => rt.i128; getUint$Buf: (a0: rt.usize) => rt.u64; getUintLe$Buf: (a0: rt.usize) => rt.u64; getUintNe$Buf: (a0: rt.usize) => rt.u64; getInt$Buf: (a0: rt.usize) => rt.i64; getIntLe$Buf: (a0: rt.usize) => rt.i64; getIntNe$Buf: (a0: rt.usize) => rt.i64; getF32$Buf: () => rt.f32; getF32Le$Buf: () => rt.f32; getF32Ne$Buf: () => rt.f32; getF64$Buf: () => rt.f64; getF64Le$Buf: () => rt.f64; getF64Ne$Buf: () => rt.f64; tryCopyToSlice$Buf: (a0: rt.ByteSlice) => rt.Result<undefined, TryGetError.TryGetError>; tryGetU8$Buf: () => rt.Result<rt.u8, TryGetError.TryGetError>; tryGetI8$Buf: () => rt.Result<rt.i8, TryGetError.TryGetError>; tryGetU16$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetU16Le$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetU16Ne$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetI16$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetI16Le$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetI16Ne$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetU32$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetU32Le$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetU32Ne$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetI32$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetI32Le$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetI32Ne$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetU64$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetU64Le$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetU64Ne$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetI64$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetI64Le$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetI64Ne$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetU128$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetU128Le$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetU128Ne$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetI128$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetI128Le$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetI128Ne$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetUint$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetUintLe$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetUintNe$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetInt$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetIntLe$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetIntNe$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetF32$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF32Le$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF32Ne$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF64$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; tryGetF64Le$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; tryGetF64Ne$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; copyToBytes$Buf: (a0: rt.usize) => rt.ByteSlice };
| { pieces$Leased: () => rt.usize; skip$Leased: (a0: Buf.Buf) => void; remaining$Buf: () => rt.usize; chunk$Buf: () => rt.ByteSlice; advance$Buf: (a0: rt.usize) => void; hasRemaining$Buf: () => boolean; copyToSlice$Buf: (a0: rt.ByteSlice) => void; getU8$Buf: () => rt.u8; getI8$Buf: () => rt.i8; getU16$Buf: () => rt.u16; getU16Le$Buf: () => rt.u16; getU16Ne$Buf: () => rt.u16; getI16$Buf: () => rt.i16; getI16Le$Buf: () => rt.i16; getI16Ne$Buf: () => rt.i16; getU32$Buf: () => rt.u32; getU32Le$Buf: () => rt.u32; getU32Ne$Buf: () => rt.u32; getI32$Buf: () => rt.i32; getI32Le$Buf: () => rt.i32; getI32Ne$Buf: () => rt.i32; getU64$Buf: () => rt.u64; getU64Le$Buf: () => rt.u64; getU64Ne$Buf: () => rt.u64; getI64$Buf: () => rt.i64; getI64Le$Buf: () => rt.i64; getI64Ne$Buf: () => rt.i64; getU128$Buf: () => rt.u128; getU128Le$Buf: () => rt.u128; getU128Ne$Buf: () => rt.u128; getI128$Buf: () => rt.i128; getI128Le$Buf: () => rt.i128; getI128Ne$Buf: () => rt.i128; getUint$Buf: (a0: rt.usize) => rt.u64; getUintLe$Buf: (a0: rt.usize) => rt.u64; getUintNe$Buf: (a0: rt.usize) => rt.u64; getInt$Buf: (a0: rt.usize) => rt.i64; getIntLe$Buf: (a0: rt.usize) => rt.i64; getIntNe$Buf: (a0: rt.usize) => rt.i64; getF32$Buf: () => rt.f32; getF32Le$Buf: () => rt.f32; getF32Ne$Buf: () => rt.f32; getF64$Buf: () => rt.f64; getF64Le$Buf: () => rt.f64; getF64Ne$Buf: () => rt.f64; tryCopyToSlice$Buf: (a0: rt.ByteSlice) => rt.Result<undefined, TryGetError.TryGetError>; tryGetU8$Buf: () => rt.Result<rt.u8, TryGetError.TryGetError>; tryGetI8$Buf: () => rt.Result<rt.i8, TryGetError.TryGetError>; tryGetU16$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetU16Le$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetU16Ne$Buf: () => rt.Result<rt.u16, TryGetError.TryGetError>; tryGetI16$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetI16Le$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetI16Ne$Buf: () => rt.Result<rt.i16, TryGetError.TryGetError>; tryGetU32$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetU32Le$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetU32Ne$Buf: () => rt.Result<rt.u32, TryGetError.TryGetError>; tryGetI32$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetI32Le$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetI32Ne$Buf: () => rt.Result<rt.i32, TryGetError.TryGetError>; tryGetU64$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetU64Le$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetU64Ne$Buf: () => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetI64$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetI64Le$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetI64Ne$Buf: () => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetU128$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetU128Le$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetU128Ne$Buf: () => rt.Result<rt.u128, TryGetError.TryGetError>; tryGetI128$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetI128Le$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetI128Ne$Buf: () => rt.Result<rt.i128, TryGetError.TryGetError>; tryGetUint$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetUintLe$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetUintNe$Buf: (a0: rt.usize) => rt.Result<rt.u64, TryGetError.TryGetError>; tryGetInt$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetIntLe$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetIntNe$Buf: (a0: rt.usize) => rt.Result<rt.i64, TryGetError.TryGetError>; tryGetF32$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF32Le$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF32Ne$Buf: () => rt.Result<rt.f32, TryGetError.TryGetError>; tryGetF64$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; tryGetF64Le$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; tryGetF64Ne$Buf: () => rt.Result<rt.f64, TryGetError.TryGetError>; copyToBytes$Buf: (a0: rt.usize) => rt.ByteSlice };

//# sourceMappingURL=buf.Leased.ts.map
12 changes: 11 additions & 1 deletion ts/fixtures/stock/expected/buf.Pieces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import * as rt from "./rt.ts";
import { out$f32, out$f64, out$i64, out$i8, out$u128, out$u16, out$u64, out$u8 } from "./lib.ts";
import type * as Provided from "./buf.Provided.ts";
import { panicAdvance, panicDoesNotFit } from "./bytes.ts";
import { signExtend } from "./bytes/buf/buf_impl.ts";
import { signExtend, hasRemaining$bytes_Buf_mut_dyn_bytes_Buf, remaining$bytes_Buf_mut_dyn_bytes_Buf } from "./bytes/buf/buf_impl.ts";
import type * as Buf from "./bytes/buf/buf_impl.Buf.ts";
import * as Chain from "./bytes/buf/chain.Chain.ts";
import { new_$mut_buf_Pieces as take_new_$mut_buf_Pieces } from "./bytes/buf/take.ts";
import type * as Take from "./bytes/buf/take.Take.ts";
Expand Down Expand Up @@ -189,6 +190,15 @@ export function pieces$buf_Leased(self: Pieces): rt.usize {
return self.parts.length;
}

/** Reads a byte of `other`, then skips as many bytes as it has left. */
export function skip$buf_Leased(self: Pieces, other: Buf.Buf): void {
if (hasRemaining$bytes_Buf_mut_dyn_bytes_Buf(other)) {
other.advance$Buf(1);
}
const _7: rt.usize = rt.min(remaining$bytes_Buf_mut_dyn_bytes_Buf(other), remaining$bytes_Buf_mut(self));
advance$bytes_Buf(self, _7);
}

/**
* Returns true if there are any more bytes to consume
*
Expand Down
6 changes: 5 additions & 1 deletion ts/fixtures/stock/expected/buf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2286,7 +2286,8 @@ export function readAll$ref_slice_u8(buf: rt.Place<rt.ByteSlice>, ops: rt.ByteSl
/**
* The reads of `reads` through a `dyn Buf` of each buffer: called on the object, through
* the impls forwarding through a `&mut` to one and a `Box` of one, and through the crate's
* own trait over `Buf`. A box drops what it owns once.
* own trait over `Buf`, whose method takes another `dyn Buf`. A box drops what it owns
* once.
*/
export function dyns(dataData: Uint8Array, dataStart: number, dataLen: number, out: rt.ByteVec): void {
let _30!: Buf.Buf;
Expand Down Expand Up @@ -2345,6 +2346,9 @@ export function dyns(dataData: Uint8Array, dataStart: number, dataLen: number, o
rt.byteVecPush(out, drops.value.v);
const leased: Leased.Leased = new of$buf_Pieces(Pieces.new(input.data, input.start, input.length, cut));
rt.byteVecPush(out, leased.pieces$Leased() & 0xff);
let skipped: rt.ByteSlice = ops2;
leased.skip$Leased(new ofPlace$ref_slice_u8(rt.place(() => skipped, (value5) => skipped = value5)));
rt.byteVecPush(out, skipped.length & 0xff);
rt.byteVecExtendFromSlice(out, rt.byteVecSlice(readAll$dyn_buf_Leased(leased, ops2, out)));
rt.byteVecPush(out, leased.pieces$Leased() & 0xff);
rt.drop(leased);
Expand Down
4 changes: 4 additions & 0 deletions ts/fixtures/stock/expected/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ export class of$buf_Pieces {
return Pieces.remaining$bytes_Buf(this.v);
}

skip$Leased(a: Buf.Buf): void {
return Pieces.skip$buf_Leased(this.v, a);
}

tryCopyToSlice$Buf(a: rt.ByteSlice): rt.Result<undefined, TryGetError.TryGetError> {
return Pieces.tryCopyToSlice$bytes_Buf(this.v, a);
}
Expand Down
15 changes: 14 additions & 1 deletion ts/fixtures/stock/src/buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,21 @@ fn read_all<B: Buf + ?Sized>(buf: &mut B, ops: &[u8], out: &mut Vec<u8>) -> Vec<
/// A buffer of the crate's own over `Buf`, as moq's transports lend a stream's chunks.
trait Leased: Buf {
fn pieces(&self) -> usize;
/// Reads a byte of `other`, then skips as many bytes as it has left.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it most naturally binds to other, which reads as "skip discards everything other still holds", but the body advances self by min(other.remaining(), self.remaining()). "then skips as many bytes as the two have left" would say that.

Suggested change
/// Reads a byte of `other`, then skips as many bytes as it has left.
/// Reads a byte of `other`, then skips as many bytes as the two have left.

fn skip(&mut self, other: &mut dyn Buf);
}

impl Leased for Pieces {
fn pieces(&self) -> usize {
self.parts.len()
}

fn skip(&mut self, other: &mut dyn Buf) {
if other.has_remaining() {
other.advance(1);
}
self.advance(other.remaining().min(self.remaining()));
}
}

/// Pieces that count their drops.
Expand Down Expand Up @@ -309,7 +318,8 @@ impl Drop for Counted {

/// The reads of `reads` through a `dyn Buf` of each buffer: called on the object, through
/// the impls forwarding through a `&mut` to one and a `Box` of one, and through the crate's
/// own trait over `Buf`. A box drops what it owns once.
/// own trait over `Buf`, whose method takes another `dyn Buf`. A box drops what it owns
/// once.
pub fn dyns(data: &[u8], out: &mut Vec<u8>) {
let [kind, cut, ops @ ..] = data else {
return;
Expand Down Expand Up @@ -351,6 +361,9 @@ pub fn dyns(data: &[u8], out: &mut Vec<u8>) {

let mut leased: Box<dyn Leased> = Box::new(Pieces::new(input, cut));
out.push(leased.pieces() as u8);
let mut skipped = ops;
leased.skip(&mut skipped);
out.push(skipped.len() as u8);
let rest = read_all(&mut *leased, ops, out);
out.extend_from_slice(&rest);
out.push(leased.pieces() as u8);
Expand Down
11 changes: 4 additions & 7 deletions ts/src/lower/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,12 +1156,9 @@ impl<'tcx> Visitor<'tcx> for BodyWrites<'_, '_, '_, 'tcx> {
&& let ty::FnDef(def_id, args) = *constant.ty().kind()
&& !self.crate_fn(def_id, args.skip_binder())
{
let sig = self
.tcx
.fn_sig(def_id)
.instantiate(self.tcx, args.skip_binder())
.skip_norm_wip();
if let Some(&this) = sig.skip_binder().inputs().first()
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args.skip_binder());
let sig = self.tcx.instantiate_bound_regions_with_erased(sig.skip_norm_wip());
if let Some(&this) = sig.inputs().first()
&& let Some(value) = replaces(self.tcx, def_id, this)
{
self.replace(value);
Expand All @@ -1181,7 +1178,7 @@ impl<'tcx> Visitor<'tcx> for BodyWrites<'_, '_, '_, 'tcx> {
}
_ => None,
};
for (i, &input) in sig.skip_binder().inputs().iter().enumerate() {
for (i, &input) in sig.inputs().iter().enumerate() {
let fresh = replace
&& call.is_some_and(|(args, made)| {
args.get(i)
Expand Down