From b7e36f324c077cd5224e0fc1b536b0b28e3b5f3e Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 13:28:18 -0800 Subject: [PATCH 01/10] chore(quest): claim quest/m3/ts-dyn.md Quest-Claim: 05c7142d7ffd6cc7 From 7bdfc32ca4b1ac833a5bea2d1954487c698d7f2b Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 15:14:11 -0800 Subject: [PATCH 02/10] feat(ts): translate TypeId, TypeId::of, and Any::type_id of values and trait objects Co-Authored-By: Claude Opus 5.5 --- ts/README.md | 18 +- ts/fixtures/lang/dyns/caller.ts | 10 +- .../lang/dyns/expected/core/any.Any.ts | 4 +- .../lang/dyns/expected/core/char/methods.ts | 27 ++ ts/fixtures/lang/dyns/expected/core/num.ts | 181 ++++++++++ ts/fixtures/lang/dyns/expected/core/option.ts | 14 + ts/fixtures/lang/dyns/expected/core/result.ts | 7 + ts/fixtures/lang/dyns/expected/dyns.Keyed.ts | 2 +- ts/fixtures/lang/dyns/expected/ids.Byte.ts | 14 + ts/fixtures/lang/dyns/expected/ids.Log.ts | 38 ++ ts/fixtures/lang/dyns/expected/ids.Marked.ts | 8 + ts/fixtures/lang/dyns/expected/ids.Mood.ts | 6 + ts/fixtures/lang/dyns/expected/ids.WithId.ts | 32 ++ ts/fixtures/lang/dyns/expected/ids.ts | 331 ++++++++++++++++++ ts/fixtures/lang/dyns/expected/lib.ts | 105 ++++++ ts/fixtures/lang/dyns/src/ids.rs | 254 ++++++++++++++ ts/fixtures/lang/dyns/src/lib.rs | 2 + ts/runtime/rs.ts | 1 + ts/runtime/rs/any.ts | 34 ++ ts/src/lower/collections.rs | 9 +- ts/src/lower/dynamic.rs | 37 +- ts/src/lower/fmt.rs | 1 + ts/src/lower/library.rs | 4 + ts/src/lower/mir/place.rs | 22 ++ ts/src/lower/mod.rs | 1 + ts/src/program.rs | 1 + 26 files changed, 1138 insertions(+), 25 deletions(-) create mode 100644 ts/fixtures/lang/dyns/expected/core/char/methods.ts create mode 100644 ts/fixtures/lang/dyns/expected/core/num.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.Byte.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.Log.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.Marked.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.Mood.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.WithId.ts create mode 100644 ts/fixtures/lang/dyns/expected/ids.ts create mode 100644 ts/fixtures/lang/dyns/src/ids.rs create mode 100644 ts/runtime/rs/any.ts diff --git a/ts/README.md b/ts/README.md index 1ad22f88b..12744f599 100644 --- a/ts/README.md +++ b/ts/README.md @@ -79,7 +79,7 @@ and each type a module of its own beside it, holding the type and its functions from. `rs.ts` beside them is the runtime: what std does that JS does not, with iterators in `rs/iter.ts`, `str`'s searches in `rs/str.ts`, the ASCII methods of `u8`, `char`, `[u8]`, and `str` in `rs/ascii.ts`, `char`'s Unicode classes, case maps, escapes, and encodings, and `str`'s case maps and escapes, in `rs/char.ts`, collections in `rs/collections.ts`, hashing in `rs/hash.ts`, ownership, atomics, and async in -`rs/task.ts`, `f64`'s and `f32`'s methods in `rs/float.ts`, `Duration` in `rs/time.ts`, and `Layout` and memory from `alloc` in `rs/alloc.ts`. What translates from std's own MIR, +`rs/task.ts`, `f64`'s and `f32`'s methods in `rs/float.ts`, `Duration` in `rs/time.ts`, `TypeId` in `rs/any.ts`, and `Layout` and memory from `alloc` in `rs/alloc.ts`. What translates from std's own MIR, `Option`'s, `Result`'s, and `Poll`'s methods, `==` of std's errors, `==` and ordering of a `Result` and a `Poll`, `cmp::max` and `min`, and the `str::parse` and `from_str_radix` of an integer or a `NonZero` and `bool`'s `str::parse`, goes in a module under its crate's name, as `core/option.ts` holds `map$1cf8u0y`. A dependency's modules go @@ -121,13 +121,14 @@ crate translation reaches is refused, and so are two versions of one crate it re | `PeekMut` | `rs.PeekMut`, the `rs.Place` of a heap's greatest element, which sifts it down as it drops once `DerefMut` lent it | | `Ordering`, `DefaultHasher`, `RandomState`, `BuildHasherDefault` | `rs.Ordering`, which is `-1`, `0`, or `1`; `rs.Hasher`; `rs.RandomState`, the keys of the `DefaultHasher` it builds, never changed once made; `undefined`, as `PhantomData` is, whose `build_hasher` is `H::default()` | | `Duration` | `rs.Duration`: `{ secs, nanos }`, std's whole seconds as an `rs.u64` and the nanoseconds past them, never changed once made | +| `TypeId` | `rs.TypeId`: rustc's 128-bit hash of the type, which std's holds at run time, as 32 hex digits, equal by `===`; ordered as std's derive orders the hash's pointer-sized words, lowest first, hashed as its high 64 bits, and written as `TypeId(0x…)`, as std's are | | `Layout`, `alloc::alloc` | `rs.Layout`: `{ size, align }`, never changed once made, checked as std's constructors check it; `alloc` gives an `rs.Block` of its bytes, which a cast of its pointer to `*mut T` the body shows came from `alloc` or `realloc` makes a JS array of `T`s, values JS copies, as an `rs.AtIndex` of its first; a cast back to `*mut u8` only as what `dealloc` or `realloc` takes, which free the array or copy it into a new one; its bytes, read, written, or cast to any other type, are refused, and fail at run time through a pointer from elsewhere | | closure | an arrow function, with `[Symbol.dispose]` if it owns a value that drops, and what makes its clone if a clone can't be itself | | `fn` pointer, function item as a value | the function, or std's an arrow that calls it as a written call does, as a closure is typed: a `()` result is `undefined`, where a declared function returns `void` | | `&dyn Trait`, `&mut dyn Trait`, `Box`, `Arc`, `Rc`, `Weak`, `Pin

` of one | an object with the trait's methods, its supertraits' included: `shape.area$Shape()`; behind an `Arc` or an `Rc`, an `rs.ArcDyn` sharing the count of the `Arc` it was made from | | a pointer to a struct whose last field unsizes to a trait object: `Rc>`, `Arc>`, `Arc>`, `&mut Cell`, `Rc>`, `Arc>`, the crate's own `&Tail` | `rs.tailDyn` of the struct it was made from: the same struct, whose other fields, borrows, and lock are that struct's own, and whose last field is the trait object a `&mut` to that field would be, made where it is read; a `dyn Future`'s polls the one future in place and drops it with the struct. A `ManuallyDrop` is the trait object of what it holds, which a box of it never drops | | `dyn Error` | an object of its `fmt$Debug` and `fmt$Display`, and its `source` where a call dispatches to it: `e.source$Error()` | -| `dyn Any` | an instance of the class its value's type was wrapped in, which a downcast checks for: `a instanceof of$dyns_Square ? a.v : undefined` | +| `dyn Any` | an instance of the class its value's type was wrapped in, which a downcast checks for: `a instanceof of$dyns_Square ? a.v : undefined`, and whose `type_id` gives that type's: `a.typeId$Any()` | | `dyn Fn`, `dyn FnMut`, `dyn FnOnce` | the closure or function it was made of: `(a0: rs.u8) => rs.u32` | | `dyn Iterator`, `dyn DoubleEndedIterator`, `dyn ExactSizeIterator`, `dyn FusedIterator` | `rs.Iter`: `rs.iterDyn` of the iterator it was made of | | constant | its value, inlined as Rust inlines it, so each use of one holding a cell is a cell of its own; one with no value tree, or holding a cell, read from the memory rustc evaluated | @@ -631,9 +632,11 @@ mapping makes, such as a `Vec`'s `io::Write`, is refused where a call dispat A `dyn Buf` holds no `chunks_vectored`, whose `IoSlice` has no JS value, so a call of it fails. -A `dyn Any` is such an object with no methods, whose class `is`, `downcast_ref`, +A `dyn Any` is such an object of `type_id` alone, whose class `is`, `downcast_ref`, `downcast_mut`, and `Box`'s, `Arc`'s, and `Rc`'s `downcast` check for: `a instanceof of$dyns_Square ? -a.v : undefined`. Its `Debug` writes `Any { .. }`, as std's does. A `&mut` one of a value JS copies is the class holding its `rs.Place`, +a.v : undefined`. Its `Debug` writes `Any { .. }`, as std's does. Its `type_id`, which it +holds once a call dispatches to it, and a crate's own trait over `Any` from the start, is a +constant of its class's type's `TypeId`, as `TypeId::of` and a value's `type_id` are. A `&mut` one of a value JS copies is the class holding its `rs.Place`, or the class itself behind a `Box`, as a `&mut dyn Trait`'s is, and `Arc::downcast` gives back the `Arc` the object was made from, or, of one made from a box, an `rs.ArcDyn` of the value sharing its count. @@ -665,7 +668,7 @@ box drops the iterator it owns, and the last `Arc` the one they share. `Arc::get `Arc` or `Weak` shares it, but a `dyn Any`'s, whose value `Arc::downcast` gives back. A trait object of a trait with a const parameter, of a byte array, or behind any other -pointer, such as a struct's last field, is refused, and so is `Any::type_id`. +pointer, such as a struct's last field, is refused. An `async fn` returns a future without running anything: an instance of a class of its own (`sumFuture`), the state machine MIR's coroutine transform makes. Its fields are the @@ -919,6 +922,11 @@ they need. `rs.Borrowed`, so it clones and drops as std's does and only the borrowed side pays a wrapper. Untagged, as `Cow` is, `to_mut` would clone on every call and a `match` would be refused; tagged, every `Cow` would be wrapped. +- A `TypeId` is the hash std's holds, rather than the class of its type, which a `&mut dyn + Any` of a value JS copies has a second of and a type no object holds has none of, or + the type's path, whose order and `Debug` are not std's. It is the crate's metadata's, so + a translation and a native build of one crate agree on which types are equal but not on + the bits. - A `Duration` keeps std's fields, whole seconds and nanoseconds, rather than one count of nanoseconds, so its overflow, `checked_*`, and ordering are std's exactly, and a lowering of its methods from core's MIR would read the same fields. diff --git a/ts/fixtures/lang/dyns/caller.ts b/ts/fixtures/lang/dyns/caller.ts index 63150528f..743e8f7ae 100644 --- a/ts/fixtures/lang/dyns/caller.ts +++ b/ts/fixtures/lang/dyns/caller.ts @@ -20,4 +20,12 @@ const shared = [[], [1], [0, 0], [255, 255, 0, 1, 2, 3, 4, 5], [7, 0xff, 255, 25 Uint8Array.of(...op("dyns::shared"), 0, ...bytes), ); -export const cases: Uint8Array[] = [...dyns, ...shared]; +/** + * `ids::ids` too short to run, and boxing each kind of value, the first two bytes picking + * ids at both ends of the list. + */ +const ids = [[], [1], [0, 12, 0, 1, 2], [12, 0, 255, 254, 253, 3]].map((bytes) => + Uint8Array.of(...op("ids::ids"), 0, ...bytes), +); + +export const cases: Uint8Array[] = [...dyns, ...shared, ...ids]; diff --git a/ts/fixtures/lang/dyns/expected/core/any.Any.ts b/ts/fixtures/lang/dyns/expected/core/any.Any.ts index ba72bb625..fd88dfe56 100644 --- a/ts/fixtures/lang/dyns/expected/core/any.Any.ts +++ b/ts/fixtures/lang/dyns/expected/core/any.Any.ts @@ -1,5 +1,7 @@ // Generated by rust2-ts. Do not edit. -export type Any = object; +import * as rs from "../rs.ts"; + +export type Any = { typeId$Any: () => rs.TypeId }; //# sourceMappingURL=any.Any.ts.map diff --git a/ts/fixtures/lang/dyns/expected/core/char/methods.ts b/ts/fixtures/lang/dyns/expected/core/char/methods.ts new file mode 100644 index 000000000..5b52ab359 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/core/char/methods.ts @@ -0,0 +1,27 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "../../rs.ts"; + +export function toDigit$14z95r4(self: rs.char, radix: rs.u32): rs.u32 | undefined { + let value!: rs.u32; + if (radix >= 2) { + if (radix <= 36) { + b1: { + if (self > 57) { + if (radix > 10) { + value = rs.u32Add((rs.u32WrappingSub(self as rs.u32, 65 as rs.u32) & 4294967263) >>> 0, 10); + break b1; + } + } + value = rs.u32WrappingSub(self as rs.u32, 48 as rs.u32); + } + if (!(value < radix)) { + return undefined; + } + return value; + } + } + rs.panicFmt(["to_digit: invalid radix -- radix must be in the range 2 to 36 inclusive"]); +} + +//# sourceMappingURL=methods.ts.map diff --git a/ts/fixtures/lang/dyns/expected/core/num.ts b/ts/fixtures/lang/dyns/expected/core/num.ts new file mode 100644 index 000000000..a60c6ad71 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/core/num.ts @@ -0,0 +1,181 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "../rs.ts"; +import { toDigit$14z95r4 } from "../core/char/methods.ts"; + +export function canNotOverflow$05izqtt(radix: rs.u32, isSignedTy: boolean, _digitsData: Uint8Array, _digitsStart: number, digitsLen: number): boolean { + if (!(radix <= 16)) { + return false; + } + return digitsLen <= rs.usizeSub(rs.usizeMul(16, 2), isSignedTy ? 1 : 0); +} + +export function fromAsciiBytesRadixPanic(radix: rs.u32): never { + doPanic$1tugyvz(radix); +} + +export function doPanic$1tugyvz(radix: rs.u32): never { + runtime$09k496w(radix); +} + +export function runtime$09k496w(radix: rs.u32): never { + rs.panicFmt(["from_ascii_bytes_radix: radix must lie in the range `[2, 36]` - found ", (f: rs.Formatter) => rs.u32Display(radix, f)]); +} + +export function fromAsciiBytesRadixImpl$0paozdl(src: rs.ByteSlice, radix: rs.u32): rs.Result { + let _12_0!: boolean; + let _12_1Data!: Uint8Array; + let _12_1Start!: number; + let _12_1Len!: number; + if (!(2 > radix)) { + if (!(radix > 36)) { + if (!(src.length === 0)) { + const isSignedTy: boolean = rs.u128Gt(0, 0); + if (src.length === 1) { + const value7 = src.data[src.start]; + if (value7 === 43 || value7 === 45) { + return rs.Err({ kind: "InvalidDigit" as rs.IntErrorKind }); + } + } + b3: { + if (src.length >= 1) { + const value8 = src.data[src.start]; + if (value8 === 43) { + _12_0 = true; + _12_1Data = src.data; + _12_1Start = src.start + 1; + _12_1Len = src.length - 1; + break b3; + } + if (value8 === 45) { + const rest2: rs.ByteSlice = rs.byteSliceRange(src, 1); + if (isSignedTy) { + _12_0 = false; + _12_1Data = rest2.data; + _12_1Start = rest2.start; + _12_1Len = rest2.length; + break b3; + } + } + } + _12_0 = true; + _12_1Data = src.data; + _12_1Start = src.start; + _12_1Len = src.length; + } + const isPositive: boolean = _12_0; + let digitsData: Uint8Array = _12_1Data; + let digitsStart: number = _12_1Start; + let digitsLen: number = _12_1Len; + let result: rs.u128 = 0; + b5: { + if (!canNotOverflow$05izqtt(radix, isSignedTy, digitsData, digitsStart, digitsLen)) { + if (!isPositive) { + while (true) { + if (!(digitsLen >= 1)) { + break b5; + } + const c4: rs.u8 = digitsData[digitsStart]; + const restData5: Uint8Array = digitsData; + const restStart5: number = digitsStart + 1; + const restLen5: number = digitsLen - 1; + const mul2: rs.u128 | undefined = rs.u128CheckedMul(result, radix as rs.u128); + const _92: rs.u32 | undefined = toDigit$14z95r4(c4 as rs.char, radix); + if (_92 === undefined) { + return rs.Err({ kind: "InvalidDigit" as rs.IntErrorKind }); + } + const x4: rs.u128 = _92 as rs.u128; + if (mul2 === undefined) { + return rs.Err({ kind: "NegOverflow" as rs.IntErrorKind }); + } + result = mul2; + const _103: rs.u128 | undefined = rs.u128CheckedSub(result, x4); + if (_103 === undefined) { + return rs.Err({ kind: "NegOverflow" as rs.IntErrorKind }); + } + result = _103; + digitsData = restData5; + digitsStart = restStart5; + digitsLen = restLen5; + } + } + while (true) { + if (!(digitsLen >= 1)) { + break b5; + } + const c3: rs.u8 = digitsData[digitsStart]; + const restData4: Uint8Array = digitsData; + const restStart4: number = digitsStart + 1; + const restLen4: number = digitsLen - 1; + const mul: rs.u128 | undefined = rs.u128CheckedMul(result, radix as rs.u128); + const _67: rs.u32 | undefined = toDigit$14z95r4(c3 as rs.char, radix); + if (_67 === undefined) { + return rs.Err({ kind: "InvalidDigit" as rs.IntErrorKind }); + } + const x3: rs.u128 = _67 as rs.u128; + if (mul === undefined) { + return rs.Err({ kind: "PosOverflow" as rs.IntErrorKind }); + } + result = mul; + const _78: rs.u128 | undefined = rs.u128CheckedAdd(result, x3); + if (_78 === undefined) { + return rs.Err({ kind: "PosOverflow" as rs.IntErrorKind }); + } + result = _78; + digitsData = restData4; + digitsStart = restStart4; + digitsLen = restLen4; + } + } + if (!isPositive) { + while (true) { + if (!(digitsLen >= 1)) { + break b5; + } + const c2: rs.u8 = digitsData[digitsStart]; + const restData3: Uint8Array = digitsData; + const restStart3: number = digitsStart + 1; + const restLen3: number = digitsLen - 1; + result = rs.u128WrappingMul(result, radix as rs.u128); + const _49: rs.u32 | undefined = toDigit$14z95r4(c2 as rs.char, radix); + if (_49 === undefined) { + return rs.Err({ kind: "InvalidDigit" as rs.IntErrorKind }); + } + result = rs.u128WrappingSub(result, _49 as rs.u128); + digitsData = restData3; + digitsStart = restStart3; + digitsLen = restLen3; + } + } + while (true) { + if (!(digitsLen >= 1)) { + break b5; + } + const c: rs.u8 = digitsData[digitsStart]; + const restData2: Uint8Array = digitsData; + const restStart2: number = digitsStart + 1; + const restLen2: number = digitsLen - 1; + result = rs.u128WrappingMul(result, radix as rs.u128); + const _32: rs.u32 | undefined = toDigit$14z95r4(c as rs.char, radix); + if (_32 === undefined) { + return rs.Err({ kind: "InvalidDigit" as rs.IntErrorKind }); + } + result = rs.u128WrappingAdd(result, _32 as rs.u128); + digitsData = restData2; + digitsStart = restStart2; + digitsLen = restLen2; + } + } + return rs.Ok(result); + } + return rs.Err({ kind: "Empty" as rs.IntErrorKind }); + } + } + fromAsciiBytesRadixPanic(radix); +} + +export function fromStrRadix$09i2k2a(src: string, radix: rs.u32): rs.Result { + return fromAsciiBytesRadixImpl$0paozdl(rs.stringAsBytes(src), radix); +} + +//# sourceMappingURL=num.ts.map diff --git a/ts/fixtures/lang/dyns/expected/core/option.ts b/ts/fixtures/lang/dyns/expected/core/option.ts index 9c9419eb5..fa808e751 100644 --- a/ts/fixtures/lang/dyns/expected/core/option.ts +++ b/ts/fixtures/lang/dyns/expected/core/option.ts @@ -27,6 +27,13 @@ export function unwrapOr$1fr498u(self: rs.u8 | undefined, default_: rs.u8): rs.u return self; } +export function unwrapOrDefault$15dio94(self: rs.u128 | undefined): rs.u128 { + if (self === undefined) { + return 0; + } + return self; +} + export function map$1rkcfqi(self: rs.Arc> | undefined, f: (a0: rs.Arc>) => rs.u32): rs.u32 | undefined { if (self === undefined) { return undefined; @@ -97,6 +104,13 @@ export function map$1aeqf1p(self: [Tagged.Tagged, Tagged.Tagged] | undefined, f: return f(self); } +export function map$1tqulv0(self: rs.u128 | undefined, f: (a0: rs.u128) => string): string | undefined { + if (self === undefined) { + return undefined; + } + return f(self); +} + export function map$070fw7m(self: rs.u32 | undefined, f: (a0: rs.u32) => rs.u32): rs.u32 | undefined { if (self === undefined) { return undefined; diff --git a/ts/fixtures/lang/dyns/expected/core/result.ts b/ts/fixtures/lang/dyns/expected/core/result.ts index 05b48d5ae..71c299dee 100644 --- a/ts/fixtures/lang/dyns/expected/core/result.ts +++ b/ts/fixtures/lang/dyns/expected/core/result.ts @@ -48,6 +48,13 @@ export function ok$1lmsnde(self: rs.Result<[rs.usize, rs.u8], rs.Arc>): return _0; } +export function ok$03r6cuf(self: rs.Result): rs.u128 | undefined { + if (self.ok) { + return self.value; + } + return undefined; +} + export function ok$1wwd922(self: rs.Result): rs.u16 | undefined { let _0!: rs.u16 | undefined; if (self.ok) { diff --git a/ts/fixtures/lang/dyns/expected/dyns.Keyed.ts b/ts/fixtures/lang/dyns/expected/dyns.Keyed.ts index 0aff1ddb4..6833a5fcb 100644 --- a/ts/fixtures/lang/dyns/expected/dyns.Keyed.ts +++ b/ts/fixtures/lang/dyns/expected/dyns.Keyed.ts @@ -3,6 +3,6 @@ import * as rs from "./rs.ts"; /** A trait over `Any`, whose objects upcast to `dyn Any`. */ -export type Keyed = { key$Keyed: () => rs.u32 }; +export type Keyed = { key$Keyed: () => rs.u32; typeId$Any: () => rs.TypeId }; //# sourceMappingURL=dyns.Keyed.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.Byte.ts b/ts/fixtures/lang/dyns/expected/ids.Byte.ts new file mode 100644 index 000000000..b9e8b04a8 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.Byte.ts @@ -0,0 +1,14 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; + +/** A value of a type of its own, which only its `TypeId` tells from a `u8`. */ +export interface Byte { + _0: rs.u8; +} + +export function tag$ids_Marked(self: Byte): rs.u8 { + return self._0; +} + +//# sourceMappingURL=ids.Byte.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.Log.ts b/ts/fixtures/lang/dyns/expected/ids.Log.ts new file mode 100644 index 000000000..93997a766 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.Log.ts @@ -0,0 +1,38 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; + +export function default$Default(): Log { + return { _0: new rs.Vec() }; +} + +/** Logs each call it is given, and how many bytes `write` is. */ +export interface Log { + _0: rs.Vec; +} + +export function write$hash_Hasher(self: Log, _bytesData: Uint8Array, _bytesStart: number, bytesLen: number): void { + const _5: string = rs.fmtFormat(["write ", (f: rs.Formatter) => rs.usizeDisplay(bytesLen, f)]); + self._0.items.push(_5); +} + +export function writeU8$hash_Hasher(self: Log, x: rs.u8): void { + const _5: string = rs.fmtFormat(["u8 ", (f: rs.Formatter) => rs.u8Display(x, f)]); + self._0.items.push(_5); +} + +export function writeU64$hash_Hasher(self: Log, x: rs.u64): void { + const _5: string = rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u64LowerHex(x, f)]); + self._0.items.push(_5); +} + +export function finish$hash_Hasher(_self: Log): rs.u64 { + return 0; +} + +/** The methods of `ids::Log`'s impl, which the runtime's hashing calls. */ +export const hasher$hash_Hasher: rs.HasherImpl = { write: (a0: Log, a1: rs.ByteSlice): undefined => { + write$hash_Hasher(a0, a1.data, a1.start, a1.length); +}, finish: finish$hash_Hasher, u8: writeU8$hash_Hasher as (a0: Log, a1: rs.u8) => undefined, u64: writeU64$hash_Hasher as (a0: Log, a1: rs.u64) => undefined }; + +//# sourceMappingURL=ids.Log.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.Marked.ts b/ts/fixtures/lang/dyns/expected/ids.Marked.ts new file mode 100644 index 000000000..9f6af73e0 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.Marked.ts @@ -0,0 +1,8 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; + +/** A trait over `Any`, whose objects give their value's `type_id`. */ +export type Marked = { tag$Marked: () => rs.u8; typeId$Any: () => rs.TypeId }; + +//# sourceMappingURL=ids.Marked.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.Mood.ts b/ts/fixtures/lang/dyns/expected/ids.Mood.ts new file mode 100644 index 000000000..b04e7af63 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.Mood.ts @@ -0,0 +1,6 @@ +// Generated by rust2-ts. Do not edit. + +/** An enum, which JS copies, so a `&mut dyn Any` of one is of a class of its place. */ +export type Mood = "Calm" | "Loud"; + +//# sourceMappingURL=ids.Mood.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.WithId.ts b/ts/fixtures/lang/dyns/expected/ids.WithId.ts new file mode 100644 index 000000000..007700e4a --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.WithId.ts @@ -0,0 +1,32 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; +import * as Log from "./ids.Log.ts"; + +export function eq$cmp_PartialEq(self: WithId, other: WithId): boolean { + if (!(self.n === other.n)) { + return false; + } + return self.id === other.id; +} + +export function cmp$cmp_Ord(self: WithId, other: WithId): rs.Ordering { + const cmp: rs.Ordering = rs.typeIdCmp(self.id, other.id); + if (cmp === 0) { + return rs.cmp(self.n, other.n); + } + return cmp; +} + +export function hash$Hash_ids_Log(self: WithId, state: Log.Log): void { + rs.typeIdHash(self.id, new rs.OwnHasher(state, Log.hasher$hash_Hasher)); + rs.hash8(self.n, new rs.OwnHasher(state, Log.hasher$hash_Hasher)); +} + +/** A `TypeId` in a struct, whose derives compare, order, and hash it as std's. */ +export interface WithId { + id: rs.TypeId; + n: rs.u8; +} + +//# sourceMappingURL=ids.WithId.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.ts b/ts/fixtures/lang/dyns/expected/ids.ts new file mode 100644 index 000000000..388d0e72c --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.ts @@ -0,0 +1,331 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; +import { of$ids_Byte, of$ids_Mood, of$ref_str, of$u32, of$u8, ofPlace$ids_Mood, ofPlace$u32 } from "./lib.ts"; +import type * as Any from "./core/any.Any.ts"; +import { fromStrRadix$09i2k2a as num_fromStrRadix$09i2k2a } from "./core/num.ts"; +import { unwrapOrDefault$15dio94 as option_unwrapOrDefault$15dio94, map$1tqulv0 as option_map$1tqulv0 } from "./core/option.ts"; +import { ok$03r6cuf } from "./core/result.ts"; +import { put } from "./harness.ts"; +import type * as Byte from "./ids.Byte.ts"; +import * as Log from "./ids.Log.ts"; +import type * as Marked from "./ids.Marked.ts"; +import type * as Mood from "./ids.Mood.ts"; +import * as WithId from "./ids.WithId.ts"; + +export function tag$ids_Marked_u8(self: rs.u8): rs.u8 { + return self; +} + +/** `T`'s `TypeId`, through a type parameter. */ +export function idOf$Option_u8(): rs.TypeId { + return "3801bd64778907c7633cf473fe556a70"; +} + +/** `T`'s `TypeId`, through a type parameter. */ +export function idOf$u8(): rs.TypeId { + return "cfb1622e7734f8af272d8d182905dc25"; +} + +/** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ +export function idOfVal$dyn_Any(_1: Any.Any): rs.TypeId { + return "f48384178e2341267f2bcf8f82c035ac"; +} + +/** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ +export function idOfVal$dyn_ids_Marked(_1: Marked.Marked): rs.TypeId { + return "21b3f780835871567b1dbe5c04134c71"; +} + +/** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ +export function idOfVal$ids_Mood(_1: Mood.Mood): rs.TypeId { + return "ff641c451ae80e5aeea189eeac47965a"; +} + +/** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ +export function idOfVal$str(_1: string): rs.TypeId { + return "b7381ee5f3fdfc9d7fa709f37e151622"; +} + +/** The 128-bit hash `Debug` writes, if it writes `TypeId(0x…)` of 32 hex digits. */ +export function hashOf(id: rs.TypeId): rs.u128 | undefined { + let _21!: boolean; + const _13: string | undefined = rs.strStripPrefix(rs.fmtFormat([(f: rs.Formatter) => rs.fmtTypeIdDebug(id, f)]), "TypeId(0x"); + if (_13 !== undefined) { + const _11: string | undefined = rs.strStripSuffix(_13, ")"); + if (_11 !== undefined) { + if (!(rs.stringLen(_11) === 32)) { + _21 = false; + } else { + _21 = rs.iterAll(rs.strBytes(_11), (b: rs.u8): boolean => { + if (!rs.isAsciiHexdigit(b)) { + return false; + } + return !rs.isAsciiUppercase(b); + }); + } + if (!_21) { + return undefined; + } + return ok$03r6cuf(num_fromStrRadix$09i2k2a(_11, 16)); + } + return undefined; + } + return undefined; +} + +/** + * The pointer-sized words of `id`'s hash as it lays them out, lowest first, which its + * derived `Ord` compares. + */ +export function words(id: rs.TypeId): rs.Vec { + const hash: rs.u128 = option_unwrapOrDefault$15dio94(hashOf(id)); + const bits: rs.u32 = 32; + const mask: rs.u128 = rs.u128Shr({ hi: 0xffffffff, w2: 0xffffffff, w1: 0xffffffff, lo: 0xffffffff } as rs.u128, rs.u32Sub(128, bits)); + return rs.iterToVec(rs.iterMap(new rs.Range(0, rs.u32Div(128, bits)), (i: rs.u32): rs.u128 => { + return rs.u128And(rs.u128Shr(hash, rs.u32Mul(i, bits)), mask); + }), undefined, 16, true); +} + +export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, out: rs.ByteVec): void { + let mood!: Mood.Mood; + let _196!: Any.Any; + let _392!: rs.TypeId; + const _486: (a0: WithId.WithId, a1: WithId.WithId) => rs.Ordering = (k: WithId.WithId, l: WithId.WithId): rs.Ordering => { + const _62: rs.Vec = words(k.id); + const _9: rs.Vec = words(l.id); + return rs.orderingThen(rs.cmpSlice(rs.cmp)(_62, _9), rs.cmp(k.n, l.n)); + }; + if (dataLen >= 2) { + const _10: [rs.u8, rs.u8] = [dataData[dataStart], dataData[dataStart + 1]]; + const a: rs.u8 = _10[0]; + const b: rs.u8 = _10[1]; + let n: rs.u32 = a as rs.u32; + if (!(rs.u8Rem(b, 2) === 0)) { + mood = "Loud" as Mood.Mood; + } else { + mood = "Calm" as Mood.Mood; + } + const byte: Byte.Byte = { _0: b }; + const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "2dfe447c5824b47a6710c76af5f599c5", "ff641c451ae80e5aeea189eeac47965a", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "21b3f780835871567b1dbe5c04134c71", "25ff997ce0b3a76fb5ce30b55accc57f"]; + const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "2dfe447c5824b47a6710c76af5f599c5", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "2dfe447c5824b47a6710c76af5f599c5", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; + const iter: rs.Iter = rs.iterSlice(found); + while (true) { + const _51: rs.TypeId | rs.Done = iter.next(); + if (_51 === rs.DONE) { + break; + } + const id: rs.TypeId = _51; + const part = rs.iterPosition(rs.iterSlice(ids), (i: rs.TypeId): boolean => { + return i === id; + }); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part, f, rs.usizeDebug), " "])); + } + const iter2: rs.Iter = rs.iterSlice([new of$u8(a), new of$u32(n), new of$ids_Byte(byte), new of$ids_Mood(mood), new of$ref_str("str")]); + while (true) { + const _87: Any.Any | rs.Done = iter2.next(); + if (_87 === rs.DONE) { + break; + } + const part2 = rs.iterPosition(rs.iterSlice(ids), (i2: rs.TypeId): boolean => { + return i2 === _87.typeId$Any(); + }); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part2, f, rs.usizeDebug), " "])); + } + const iter3: rs.Iter = rs.iterSlice([new ofPlace$u32(rs.place(() => n, (value) => n = value)), new ofPlace$ids_Mood(rs.place(() => mood, (value2) => mood = value2))]); + while (true) { + const _116: Any.Any | rs.Done = iter3.next(); + if (_116 === rs.DONE) { + break; + } + const part3 = rs.iterPosition(rs.iterSlice(ids), (i3: rs.TypeId): boolean => { + return i3 === _116.typeId$Any(); + }); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part3, f, rs.usizeDebug), " "])); + } + const iter4: rs.Iter = rs.iterSlice([new of$u8(a), new of$ids_Byte(byte)]); + while (true) { + const _146: Marked.Marked | rs.Done = iter4.next(); + if (_146 === rs.DONE) { + break; + } + const any: Any.Any = _146; + const _159: rs.u8 = _146.tag$Marked(); + const _161: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i4: rs.TypeId): boolean => { + return i4 === _146.typeId$Any(); + }); + const _168: boolean = _146.typeId$Any() === any.typeId$Any(); + const _174: boolean = idOfVal$dyn_ids_Marked(_146) === "21b3f780835871567b1dbe5c04134c71"; + const args32 = [(f: rs.Formatter) => rs.u8Display(_159, f), (f: rs.Formatter) => rs.fmtOption(_161, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_168, f), (f: rs.Formatter) => rs.fmtBool(_174, f)]; + put(out, rs.fmtFormat([args32[0], " ", args32[1], " ", args32[2], " ", args32[3], " "])); + } + const boxes: rs.Vec = new rs.Vec(); + for (const x of rs.byteSliceView(new rs.ByteSlice(dataData, dataStart + 2, dataLen - 2))) { + const _197: rs.u8 = rs.u8Rem(x, 3); + if (_197 === 0) { + _196 = new of$u8(x); + } else if (_197 === 1) { + _196 = new of$ids_Byte({ _0: x }); + } else { + _196 = new of$ids_Mood("Loud" as Mood.Mood); + } + boxes.items.push(_196); + } + for (const _207 of boxes.items) { + const inner: rs.TypeId = _207.typeId$Any(); + const _221: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i5: rs.TypeId): boolean => { + return i5 === inner; + }); + const _229: boolean = "37a732caafaf8e089d3a9d4c07b2ec78" === "37a732caafaf8e089d3a9d4c07b2ec78"; + const args33 = [(f: rs.Formatter) => rs.fmtOption(_221, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_229, f)]; + put(out, rs.fmtFormat([args33[0], " ", args33[1], " "])); + } + const _240: rs.Arc = new rs.Arc(byte); + const shared: rs.Arc = new rs.ArcDyn(_240, new of$ids_Byte(_240.value)); + const boxed: Marked.Marked = new of$u8(a); + const _251: boolean = shared.value.typeId$Any() === "2dfe447c5824b47a6710c76af5f599c5"; + const _259: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; + const _266: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; + const args34 = [(f: rs.Formatter) => rs.fmtBool(_251, f), (f: rs.Formatter) => rs.fmtBool(_259, f), (f: rs.Formatter) => rs.fmtBool(_266, f)]; + put(out, rs.fmtFormat([args34[0], " ", args34[1], " ", args34[2], " "])); + const _279: rs.Slice = rs.sliceFrom(ids); + const pairs: () => rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> = (): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { + return rs.iterFlatMap(rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_279))), (_210: [rs.usize, rs.TypeId]): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { + const i6: rs.usize = _210[0]; + const x3: rs.TypeId = _210[1]; + const _52: rs.Iter<[rs.usize, rs.TypeId]> = rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_279))); + const captured = i6; + const captured2 = x3; + return rs.iterMap(_52, (_211: [rs.usize, rs.TypeId]): [rs.usize, rs.TypeId, rs.usize, rs.TypeId] => { + return [captured, captured2, _211[0], _211[1]] as [rs.usize, rs.TypeId, rs.usize, rs.TypeId]; + }); + }, undefined, true); + }; + const _288: boolean = rs.iterAll(pairs(), (_212: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const i7: rs.usize = _212[0]; + const x4: rs.TypeId = _212[1]; + const j2: rs.usize = _212[2]; + const y3: rs.TypeId = _212[3]; + if (!(x4 === y3 === (i7 === j2))) { + return false; + } + return x4 !== y3 === (i7 !== j2); + }); + const _293: boolean = rs.iterAll(pairs(), (_213: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const x5: rs.TypeId = _213[1]; + const y4: rs.TypeId = _213[3]; + const _610: rs.Ordering = rs.typeIdCmp(x5, y4); + const _127: rs.Vec = words(x5); + const _143: rs.Vec = words(y4); + return _610 === rs.cmpSlice(rs.cmp)(_127, _143); + }); + const _298: boolean = rs.iterAll(pairs(), (_215: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const x6: rs.TypeId = _215[1]; + const y5: rs.TypeId = _215[3]; + const _611: rs.Ordering | undefined = rs.typeIdCmp(x6, y5); + const _134: rs.Vec = words(x6); + const _157: rs.Vec = words(y5); + return _611 === rs.cmpSlice(rs.cmp)(_134, _157) as rs.Ordering | undefined; + }); + const _303: boolean = rs.iterAll(pairs(), (_219: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const x7: rs.TypeId = _219[1]; + const y6: rs.TypeId = _219[3]; + const _612: boolean = rs.typeIdCmp(x7, y6) === -1; + const _1112: rs.Vec = words(x7); + const _139: rs.Vec = words(y6); + if (!(_612 === (rs.cmpSlice(rs.cmp)(_1112, _139) === -1))) { + return false; + } + const order2 = rs.typeIdCmp(x7, y6); + const _145: boolean = order2 !== undefined && order2 >= 0; + const _192: rs.Vec = words(x7); + const _2110: rs.Vec = words(y6); + const order3 = rs.cmpSlice(rs.cmp)(_192, _2110); + return _145 === (order3 !== undefined && order3 >= 0); + }); + const args35 = [(f: rs.Formatter) => rs.fmtBool(_288, f), (f: rs.Formatter) => rs.fmtBool(_293, f), (f: rs.Formatter) => rs.fmtBool(_298, f), (f: rs.Formatter) => rs.fmtBool(_303, f)]; + put(out, rs.fmtFormat([args35[0], " ", args35[1], " ", args35[2], " ", args35[3], " "])); + const _318: rs.usize = rs.usizeRem(a as rs.usize, rs.sliceFrom(ids).length); + if (!(_318 < 13)) { + rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _318); + } + const _317: rs.TypeId = ids[_318]; + const _326: rs.usize = rs.usizeRem(b as rs.usize, rs.sliceFrom(ids).length); + if (!(_326 < 13)) { + rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _326); + } + const _316: [rs.TypeId, rs.TypeId] = [_317, ids[_326]]; + const x2: rs.TypeId = _317; + const y: rs.TypeId = _316[1]; + const part4 = rs.iterAll(rs.iterSlice(ids), (_220: rs.TypeId): boolean => { + return hashOf(_220) !== undefined; + }); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(part4, f), " "])); + const log: Log.Log = Log.default$Default(); + rs.typeIdHash(x2, new rs.OwnHasher(log, Log.hasher$hash_Hasher)); + const high: string | undefined = option_map$1tqulv0(hashOf(x2), (h: rs.u128): string => { + const part5 = rs.u128Shr(h, 64); + return rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u128LowerHex(part5, f)]); + }); + const _364: rs.usize = log._0.items.length; + const _367: boolean = rs.sliceFirst(rs.sliceFrom(log._0.items)) === high; + const args40 = [(f: rs.Formatter) => rs.usizeDisplay(_364, f), (f: rs.Formatter) => rs.fmtBool(_367, f)]; + put(out, rs.fmtFormat([args40[0], " ", args40[1], " "])); + const _390: rs.TypeId = rs.ordMax(x2, y, rs.cmpLt(rs.typeIdCmp)); + const _395: rs.Vec = words(x2); + const _397: rs.Vec = words(y); + if (!(rs.cmpSlice(rs.cmp)(_395, _397) === -1)) { + _392 = x2; + } else { + _392 = y; + } + const arg = _390 === _392; + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(arg, f), " "])); + const sorted: rs.Vec = rs.vecFrom(ids.slice()); + rs.sliceSort(rs.sliceFrom(sorted.items), rs.cmpLt(rs.typeIdCmp), 16, true); + const ordered: boolean = rs.iterAll(rs.sliceWindows(rs.sliceFrom(sorted.items), 2), (w: rs.Slice): boolean => { + rs.idx(w, 0); + const _429: rs.Vec = words(w.data[w.start]); + rs.idx(w, 1); + const _1011: rs.Vec = words(w.data[w.start + 1]); + return rs.cmpSlice(rs.cmp)(_429, _1011) === -1; + }); + const _414: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.typeIdCmp) as rs.BTreeSet, _414, true, undefined, undefined, 16, true); + const _421: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const hashed: rs.HashSet = rs.hashExtendKeys(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashSet, _421, undefined, undefined, 58720256); + const _435: rs.usize = rs.btreeLen(set); + const _438: rs.usize = rs.hashLen(hashed); + const args42 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_435, f), (f: rs.Formatter) => rs.usizeDisplay(_438, f)]; + put(out, rs.fmtFormat([args42[0], " ", args42[1], " ", args42[2], " "])); + const _448: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["2dfe447c5824b47a6710c76af5f599c5", "byte"] as [rs.TypeId, string], ["ff641c451ae80e5aeea189eeac47965a", "mood"] as [rs.TypeId, string]]); + const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _448, undefined, undefined, undefined, 58720256); + for (const _461 of boxes.items) { + const part6 = rs.hashGet(names, _461.typeId$Any()); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part6, f, rs.fmtStr), " "])); + } + const keys: WithId.WithId[] = [{ id: x2, n: a }, { id: y, n: b }, { id: x2, n: b }]; + const _494: rs.Slice = rs.sliceFrom(keys); + const part9 = rs.iterToVec(rs.iterMap(rs.iterFlatMap(rs.iterSlice(keys), (k2: WithId.WithId): rs.Iter<[WithId.WithId, WithId.WithId]> => { + return rs.iterMap(rs.iterSlice(rs.sliceItems(_494)), (l2: WithId.WithId): [WithId.WithId, WithId.WithId] => { + return [k2, l2] as [WithId.WithId, WithId.WithId]; + }); + }, undefined, true), (_222: [WithId.WithId, WithId.WithId]): [boolean, boolean] => { + const k3: WithId.WithId = _222[0]; + const l3: WithId.WithId = _222[1]; + return [WithId.eq$cmp_PartialEq(k3, l3), WithId.cmp$cmp_Ord(k3, l3) === _486(k3, l3)] as [boolean, boolean]; + }), "next", 2); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(part9.items, f, (value: [boolean, boolean], f: rs.Formatter) => rs.fmtTuple([(f: rs.Formatter) => rs.fmtBool(value[0], f), (f: rs.Formatter) => rs.fmtBool(value[1], f)], f)), " "])); + const log2: Log.Log = Log.default$Default(); + WithId.hash$Hash_ids_Log(keys[0], log2); + const _523: rs.usize = log2._0.items.length; + const _526: string | undefined = rs.sliceGet(rs.sliceFrom(log2._0.items), 1); + const args45 = [(f: rs.Formatter) => rs.usizeDisplay(_523, f), (f: rs.Formatter) => rs.fmtOption(_526, f, rs.fmtStr)]; + put(out, rs.fmtFormat([args45[0], " ", args45[1]])); + rs.drop(boxed); + shared[Symbol.dispose](); + rs.dropVec(boxes); + } +} + +//# sourceMappingURL=ids.ts.map diff --git a/ts/fixtures/lang/dyns/expected/lib.ts b/ts/fixtures/lang/dyns/expected/lib.ts index 62a9c5b58..c56e7d3bc 100644 --- a/ts/fixtures/lang/dyns/expected/lib.ts +++ b/ts/fixtures/lang/dyns/expected/lib.ts @@ -20,6 +20,9 @@ import * as Square from "./dyns.Square.ts"; import * as Steps from "./dyns.Steps.ts"; import type * as Tagged from "./dyns.Tagged.ts"; import * as Tri from "./dyns.Tri.ts"; +import { tag$ids_Marked_u8, ids } from "./ids.ts"; +import * as Byte from "./ids.Byte.ts"; +import type * as Mood from "./ids.Mood.ts"; import { dynHash$stds_DynHash_ref_str, dynHash$stds_DynHash_u8, stds } from "./stds.ts"; import * as Counter from "./stds.Counter.ts"; import * as Fnv from "./stds.Fnv.ts"; @@ -330,6 +333,10 @@ export class of$Option_u8 { constructor(v: rs.u8 | undefined) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "3801bd64778907c7633cf473fe556a70"; + } } export class of$dyns_By { @@ -534,6 +541,10 @@ export class of$dyns_Noisy { tally$Shape(a: rs.Place): void { return Noisy.tally$dyns_Shape(this.v, a); } + + typeId$Any(): rs.TypeId { + return "6ee750ef237f822811c4976fd472b245"; + } } export class of$dyns_Square { @@ -590,6 +601,10 @@ export class of$dyns_Square { tally$Shape(a: rs.Place): void { return Square.tally$dyns_Shape(this.v, a); } + + typeId$Any(): rs.TypeId { + return "2b2edbfca4a483b1f8ee1dc4a77120d6"; + } } export class of$dyns_Steps { @@ -678,6 +693,10 @@ export class of$dyns_Tri { tally$Shape(a: rs.Place): void { return Tri.tally$dyns_Shape(this.v, a); } + + typeId$Any(): rs.TypeId { + return "ed63cd53a1500717929949d6660c4beb"; + } } export class of$fmt_Formatter { @@ -772,6 +791,34 @@ export class of$hash_DefaultHasher { } } +export class of$ids_Byte { + v: Byte.Byte; + + constructor(v: Byte.Byte) { + this.v = v; + } + + tag$Marked(): rs.u8 { + return Byte.tag$ids_Marked(this.v); + } + + typeId$Any(): rs.TypeId { + return "2dfe447c5824b47a6710c76af5f599c5"; + } +} + +export class of$ids_Mood { + v: Mood.Mood; + + constructor(v: Mood.Mood) { + this.v = v; + } + + typeId$Any(): rs.TypeId { + return "ff641c451ae80e5aeea189eeac47965a"; + } +} + export class of$ref_str { v: string; @@ -782,6 +829,10 @@ export class of$ref_str { dynHash$DynHash(a: Hasher.Hasher): void { return dynHash$stds_DynHash_ref_str(this.v, a); } + + typeId$Any(): rs.TypeId { + return "24c161f26c70c1f1b9f602dc5fe9f65c"; + } } export class of$stds_Counter { @@ -1020,6 +1071,10 @@ export class of$tuple2_u8_u8 { constructor(v: [rs.u8, rs.u8]) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "7d311253455a5117c9570c9455e07dcc"; + } } export class of$u16 { @@ -1088,6 +1143,10 @@ export class of$u32 { tally$Shape(a: rs.Place): void { return tally$dyns_Shape_u32(this.v, a); } + + typeId$Any(): rs.TypeId { + return "79f19461b401588885a89e43144b08f1"; + } } export class of$u8 { @@ -1105,9 +1164,17 @@ export class of$u8 { return left$dyns_Source_u8(this.v); } + tag$Marked(): rs.u8 { + return tag$ids_Marked_u8(this.v); + } + take$Source(): string | undefined { return dyns_take$dyns_Source_u8(this); } + + typeId$Any(): rs.TypeId { + return "cfb1622e7734f8af272d8d182905dc25"; + } } export class of$unit { @@ -1116,6 +1183,10 @@ export class of$unit { constructor(v: undefined) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "05fc01408e45e7cddf9e041e3391eafc"; + } } export class ofPlace$Option_u8 { @@ -1124,6 +1195,10 @@ export class ofPlace$Option_u8 { constructor(v: rs.Place) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "3801bd64778907c7633cf473fe556a70"; + } } export class ofPlace$String { @@ -1224,6 +1299,22 @@ export class ofPlace$dyns_Tri { tally$Shape(a: rs.Place): void { return Tri.tally$dyns_Shape(this.v.v, a); } + + typeId$Any(): rs.TypeId { + return "ed63cd53a1500717929949d6660c4beb"; + } +} + +export class ofPlace$ids_Mood { + v: rs.Place; + + constructor(v: rs.Place) { + this.v = v; + } + + typeId$Any(): rs.TypeId { + return "ff641c451ae80e5aeea189eeac47965a"; + } } export class ofPlace$mut_String { @@ -1292,6 +1383,10 @@ export class ofPlace$u32 { tally$Shape(a: rs.Place): void { return tally$dyns_Shape_u32(this.v.v, a); } + + typeId$Any(): rs.TypeId { + return "79f19461b401588885a89e43144b08f1"; + } } export class ofPlace$u8 { @@ -1308,6 +1403,10 @@ export class ofPlace$u8 { take$Source(): string | undefined { return dyns_take$dyns_Source_u8(this.v); } + + typeId$Any(): rs.TypeId { + return "cfb1622e7734f8af272d8d182905dc25"; + } } export class ofPlace$unit { @@ -1316,6 +1415,10 @@ export class ofPlace$unit { constructor(v: rs.Place) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "05fc01408e45e7cddf9e041e3391eafc"; + } } /** @@ -1345,6 +1448,8 @@ export function cases(): rs.Vec<[string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.By generics(data10, out10); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["stds::stds", (_220: rs.u8, data11: rs.ByteSlice, out11: rs.ByteVec): undefined => { stds(data11, out11); + }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["ids::ids", (_221: rs.u8, data12: rs.ByteSlice, out12: rs.ByteVec): undefined => { + ids(data12.data, data12.start, data12.length, out12); }] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]]); } diff --git a/ts/fixtures/lang/dyns/src/ids.rs b/ts/fixtures/lang/dyns/src/ids.rs new file mode 100644 index 000000000..52c513a17 --- /dev/null +++ b/ts/fixtures/lang/dyns/src/ids.rs @@ -0,0 +1,254 @@ +//! `TypeId`s, of `TypeId::of`, of a value's `type_id`, and of a trait object's, which is +//! its value's type's: borrowed, changed in place, boxed, shared, and upcast from the +//! crate's own trait over `Any`, but for a box or an `Rc`'s own `type_id`, which is the +//! pointer's type's. Each is equal to another only for the same type, in a struct's +//! derives, a hash map, and a `BTreeSet` too. Its value is the crate's metadata's, so each +//! check compares within a run: `Debug` writes `TypeId(0x…)` of its 128-bit hash, `Ord` +//! orders by that hash's pointer-sized words, lowest first, and `Hash` writes one `u64`, +//! the hash's high half. + +use std::any::{Any, TypeId}; +use std::collections::{BTreeSet, HashMap, HashSet}; +use std::hash::{Hash, Hasher}; +use std::rc::Rc; + +use crate::harness::put; + +/// A value of a type of its own, which only its `TypeId` tells from a `u8`. +#[derive(Debug, Clone, Copy)] +struct Byte(u8); + +/// An enum, which JS copies, so a `&mut dyn Any` of one is of a class of its place. +enum Mood { + Calm, + Loud, +} + +/// A trait over `Any`, whose objects give their value's `type_id`. +trait Marked: Any { + fn tag(&self) -> u8; +} + +impl Marked for u8 { + fn tag(&self) -> u8 { + *self + } +} + +impl Marked for Byte { + fn tag(&self) -> u8 { + self.0 + } +} + +/// A `TypeId` in a struct, whose derives compare, order, and hash it as std's. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct WithId { + id: TypeId, + n: u8, +} + +/// Logs each call it is given, and how many bytes `write` is. +#[derive(Default)] +struct Log(Vec); + +impl Hasher for Log { + fn write(&mut self, bytes: &[u8]) { + self.0.push(format!("write {}", bytes.len())); + } + fn write_u8(&mut self, x: u8) { + self.0.push(format!("u8 {x}")); + } + fn write_u64(&mut self, x: u64) { + self.0.push(format!("u64 {x:x}")); + } + fn finish(&self) -> u64 { + 0 + } +} + +/// A `TypeId` the compiler evaluates. +const U8: TypeId = TypeId::of::(); + +/// `T`'s `TypeId`, through a type parameter. +fn id_of() -> TypeId { + TypeId::of::() +} + +/// The `TypeId` of what `x` is, through a type parameter that may be a trait object. +fn id_of_val(_: &T) -> TypeId { + TypeId::of::() +} + +/// The 128-bit hash `Debug` writes, if it writes `TypeId(0x…)` of 32 hex digits. +fn hash_of(id: TypeId) -> Option { + let s = format!("{id:?}"); + let digits = s.strip_prefix("TypeId(0x")?.strip_suffix(')')?; + match digits.len() == 32 && digits.bytes().all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase()) { + true => u128::from_str_radix(digits, 16).ok(), + false => None, + } +} + +/// The pointer-sized words of `id`'s hash as it lays them out, lowest first, which its +/// derived `Ord` compares. +fn words(id: TypeId) -> Vec { + let hash = hash_of(id).unwrap_or_default(); + let bits = usize::BITS; + let mask = u128::MAX >> (128 - bits); + (0..128 / bits).map(|i| (hash >> (i * bits)) & mask).collect() +} + +pub fn ids(data: &[u8], out: &mut Vec) { + let [a, b, rest @ ..] = data else { + return; + }; + let (a, b) = (*a, *b); + + // A type's own, through a type parameter, of a value, and of a trait object of a value. + let mut n = u32::from(a); + let mut mood = if b % 2 == 0 { Mood::Calm } else { Mood::Loud }; + let byte = Byte(b); + let ids = [ + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::<&'static str>(), + TypeId::of::(), + TypeId::of::<()>(), + TypeId::of::>(), + TypeId::of::<[u8]>(), + TypeId::of::(), + TypeId::of::>(), + TypeId::of::(), + TypeId::of:: u8>(), + ]; + let found = [ + id_of::(), + U8, + const { TypeId::of::() }, + a.type_id(), + n.type_id(), + byte.type_id(), + id_of_val("str"), + id_of_val(&mood), + id_of_val::(&a), + id_of::>(), + ]; + for id in found { + put(out, &format!("{:?} ", ids.iter().position(|i| *i == id))); + } + + // A trait object's is its value's, borrowed, changed in place, which JS copies for a + // number and an enum, boxed, shared, and upcast, but a box's and an `Rc`'s own are theirs. + let objects: [&dyn Any; 5] = [&a, &n, &byte, &mood, &"str"]; + for x in objects { + put(out, &format!("{:?} ", ids.iter().position(|i| *i == x.type_id()))); + } + let places: [&mut dyn Any; 2] = [&mut n, &mut mood]; + for x in places { + put(out, &format!("{:?} ", ids.iter().position(|i| *i == (*x).type_id()))); + } + let marked: [&dyn Marked; 2] = [&a, &byte]; + for t in marked { + let any: &dyn Any = t; + put( + out, + &format!( + "{} {:?} {} {} ", + t.tag(), + ids.iter().position(|i| *i == t.type_id()), + t.type_id() == any.type_id(), + id_of_val(t) == TypeId::of::(), + ), + ); + } + let mut boxes: Vec> = Vec::new(); + for &x in rest { + boxes.push(match x % 3 { + 0 => Box::new(x), + 1 => Box::new(Byte(x)), + _ => Box::new(Mood::Loud), + }); + } + for x in &boxes { + let inner = (**x).type_id(); + put( + out, + &format!( + "{:?} {} ", + ids.iter().position(|i| *i == inner), + x.type_id() == TypeId::of::>() + ), + ); + } + let shared: Rc = Rc::new(byte); + let boxed: Box = Box::new(a); + put( + out, + &format!( + "{} {} {} ", + (*shared).type_id() == TypeId::of::(), + shared.type_id() == TypeId::of::>(), + (*boxed).type_id() == TypeId::of::(), + ), + ); + + // Equal only for the same type, ordered by its hash's words lowest first, and hashed as + // one `u64`, its hash's high half, written alone. + let pairs = || { + ids.iter() + .enumerate() + .flat_map(|(i, &x)| ids.iter().enumerate().map(move |(j, &y)| (i, x, j, y))) + }; + put( + out, + &format!( + "{} {} {} {} ", + pairs().all(|(i, x, j, y)| (x == y) == (i == j) && (x != y) == (i != j)), + pairs().all(|(_, x, _, y)| x.cmp(&y) == words(x).cmp(&words(y))), + pairs().all(|(_, x, _, y)| x.partial_cmp(&y) == Some(words(x).cmp(&words(y)))), + pairs().all(|(_, x, _, y)| (x < y) == (words(x) < words(y)) && (x >= y) == (words(x) >= words(y))), + ), + ); + let (x, y) = (ids[usize::from(a) % ids.len()], ids[usize::from(b) % ids.len()]); + put(out, &format!("{} ", ids.iter().all(|&id| hash_of(id).is_some()))); + let mut log = Log::default(); + x.hash(&mut log); + let high = hash_of(x).map(|h| format!("u64 {:x}", h >> 64)); + put(out, &format!("{} {} ", log.0.len(), log.0.first() == high.as_ref())); + put( + out, + &format!("{} ", x.max(y) == if words(x) < words(y) { y } else { x }), + ); + + // Sorted, in sets and maps, and in a struct's derives. + let mut sorted = ids.to_vec(); + sorted.sort(); + let ordered = sorted.windows(2).all(|w| words(w[0]) < words(w[1])); + let set: BTreeSet = ids.iter().chain(&found).copied().collect(); + let hashed: HashSet = ids.iter().chain(&found).copied().collect(); + put(out, &format!("{ordered} {} {} ", set.len(), hashed.len())); + let names: HashMap = [ + (TypeId::of::(), "u8"), + (TypeId::of::(), "byte"), + (TypeId::of::(), "mood"), + ] + .into_iter() + .collect(); + for x in &boxes { + put(out, &format!("{:?} ", names.get(&(**x).type_id()))); + } + let keys = [WithId { id: x, n: a }, WithId { id: y, n: b }, WithId { id: x, n: b }]; + let by_id = |k: &WithId, l: &WithId| words(k.id).cmp(&words(l.id)).then(k.n.cmp(&l.n)); + let order: Vec<(bool, bool)> = keys + .iter() + .flat_map(|k| keys.iter().map(move |l| (k, l))) + .map(|(k, l)| (k == l, k.cmp(l) == by_id(k, l))) + .collect(); + put(out, &format!("{order:?} ")); + let mut log = Log::default(); + keys[0].hash(&mut log); + put(out, &format!("{} {:?}", log.0.len(), log.0.get(1))); +} diff --git a/ts/fixtures/lang/dyns/src/lib.rs b/ts/fixtures/lang/dyns/src/lib.rs index 0450248f4..1f81066cd 100644 --- a/ts/fixtures/lang/dyns/src/lib.rs +++ b/ts/fixtures/lang/dyns/src/lib.rs @@ -4,6 +4,7 @@ mod dyns; #[path = "../../harness.rs"] pub mod harness; +mod ids; mod stds; #[cfg(target_arch = "wasm32")] #[path = "../../../wasm.rs"] @@ -28,5 +29,6 @@ fn cases() -> Vec<(&'static str, Case)> { ("dyns::rests", |_, data, out| dyns::rests(data, out)), ("dyns::generics", |_, data, out| dyns::generics(data, out)), ("stds::stds", |_, data, out| stds::stds(data, out)), + ("ids::ids", |_, data, out| ids::ids(data, out)), ] } diff --git a/ts/runtime/rs.ts b/ts/runtime/rs.ts index f4c095417..d5e02fd22 100644 --- a/ts/runtime/rs.ts +++ b/ts/runtime/rs.ts @@ -18,6 +18,7 @@ import { AtIndex } from "./rs/collections.ts"; import { escapeDebug } from "./rs/char.ts"; import { strFromUtf8Unchecked } from "./rs/str.ts"; export * from "./rs/alloc.ts"; +export * from "./rs/any.ts"; export * from "./rs/ascii.ts"; export * from "./rs/bytes.ts"; export * from "./rs/char.ts"; diff --git a/ts/runtime/rs/any.ts b/ts/runtime/rs/any.ts new file mode 100644 index 000000000..d55f35978 --- /dev/null +++ b/ts/runtime/rs/any.ts @@ -0,0 +1,34 @@ +// `core::any::TypeId`, for rust2-ts output. `rs.ts` re-exports all of it. + +import { type FmtResult, type Formatter, fmtWriteStr } from "../rs.ts"; +import { cmpStr, type Ordering } from "./collections.ts"; +import { type Hasher, hash64 } from "./hash.ts"; +import { u64FromHalves } from "./int.ts"; + +/** + * `TypeId`: rustc's 128-bit hash of the type, which std's holds at run time, as 32 + * lowercase hex digits, so two are equal by `===`. + */ +export type TypeId = string; + +/** + * `Ord::cmp`, derived over the pointer-sized words std lays the hash out in, lowest first, + * as wasm32's are: each is 8 hex digits, which compare as their numbers do. + */ +export function typeIdCmp(a: TypeId, b: TypeId): Ordering { + for (let end = 32; end > 0; end -= 8) { + const order = cmpStr(a.slice(end - 8, end), b.slice(end - 8, end)); + if (order !== 0) return order; + } + return 0; +} + +/** `Hash::hash`: the hash's high 64 bits, the second half of its bytes, as one `u64`. */ +export function typeIdHash(id: TypeId, s: Hasher): void { + hash64(u64FromHalves(parseInt(id.slice(0, 8), 16), parseInt(id.slice(8, 16), 16)), s); +} + +/** `Debug`, as std's: `TypeId(0x…)` of the hash's 32 digits, which no width pads. */ +export function fmtTypeIdDebug(id: TypeId, f: Formatter): FmtResult { + return fmtWriteStr(f, `TypeId(0x${id})`); +} diff --git a/ts/src/lower/collections.rs b/ts/src/lower/collections.rs index 86ff10302..a28341d0f 100644 --- a/ts/src/lower/collections.rs +++ b/ts/src/lower/collections.rs @@ -2760,7 +2760,7 @@ fn std_key<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { library::string(b.t.tcx, ty) || matches!( b.t.std_of(ty), - Some(Std::Ordering | Std::Duration | Std::Location | Std::TryReserveError) + Some(Std::Ordering | Std::Duration | Std::TypeId | Std::Location | Std::TryReserveError) ) } _ => false, @@ -3008,6 +3008,7 @@ pub fn cmp_fn<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, partial: bool, spa ty::Adt(..) if library::string(tcx, ty) => Expr::Rs("cmpStr".into()), ty::Adt(..) if b.t.std_of(ty) == Some(Std::Ordering) => Expr::Rs("cmp".into()), ty::Adt(..) if b.t.std_of(ty) == Some(Std::Duration) => Expr::Rs("durationCmp".into()), + ty::Adt(..) if b.t.std_of(ty) == Some(Std::TypeId) => Expr::Rs("typeIdCmp".into()), ty::Adt(..) if b.t.std_of(ty) == Some(Std::Location) => Expr::Rs("locationCmp".into()), _ if library::nothing(tcx, ty) => Expr::Rs("cmpNothing".into()), ty::Tuple(tys) => { @@ -3083,7 +3084,10 @@ pub fn eq_fn<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, span: Span) -> Expr } ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => Expr::Rs("same".into()), _ if library::nothing(tcx, ty) => Expr::Rs("same".into()), - ty::Adt(..) if library::string(tcx, ty) || matches!(b.t.std_of(ty), Some(Std::Ordering | Std::ErrorKind)) => { + ty::Adt(..) + if library::string(tcx, ty) + || matches!(b.t.std_of(ty), Some(Std::Ordering | Std::ErrorKind | Std::TypeId)) => + { Expr::Rs("same".into()) } ty::Adt(..) if b.t.std_of(ty) == Some(Std::Duration) => Expr::Rs("durationEq".into()), @@ -3320,6 +3324,7 @@ fn hash_fn<'tcx>(b: &mut Body<'_, '_, 'tcx>, ty: Ty<'tcx>, hasher: Ty<'tcx>, spa // Its derived `Hash` writes its `i8` discriminant. ty::Adt(..) if b.t.std_of(ty) == Some(Std::Ordering) => Expr::Rs("hashI8".into()), ty::Adt(..) if b.t.std_of(ty) == Some(Std::Duration) => Expr::Rs("durationHash".into()), + ty::Adt(..) if b.t.std_of(ty) == Some(Std::TypeId) => Expr::Rs("typeIdHash".into()), ty::Adt(..) if b.t.std_of(ty) == Some(Std::Location) => Expr::Rs("locationHash".into()), _ if library::nothing(tcx, ty) => Expr::Rs("hashNothing".into()), ty::Tuple(tys) => { diff --git a/ts/src/lower/dynamic.rs b/ts/src/lower/dynamic.rs index bfc60fb65..0a275e811 100644 --- a/ts/src/lower/dynamic.rs +++ b/ts/src/lower/dynamic.rs @@ -11,8 +11,8 @@ //! struct whose last field unsizes to one, such as a `RefCell`, is an //! `rs.tailDyn` view of the struct it was made from, whose last field is that field's //! object. A raw pointer unsizes as a `&mut` to what it points at does. A -//! `dyn Any` has no methods, and a downcast, of it or of a `dyn Error`, checks for the -//! class of the type it names. A `dyn Fn`, +//! `dyn Any`'s one method is `type_id`, a constant of its class's type's `TypeId`, and a +//! downcast, of it or of a `dyn Error`, checks for the class of the type it names. A `dyn Fn`, //! `dyn FnMut`, or `dyn FnOnce` is the function it was made of, which a call calls as it //! would the closure itself. @@ -117,6 +117,15 @@ impl<'tcx> Translator<'_, 'tcx> { }) } + /// `ty`'s `TypeId`: rustc's hash of it, as 32 hex digits, or `undefined` in a census over + /// type parameters, where only an instance decides what `ty` is. + pub fn type_id(&self, ty: Ty<'tcx>) -> Expr { + match self.polymorphic() && ty.has_param() { + true => Expr::undefined(), + false => Expr::Str(format!("{:032x}", self.tcx.type_id_hash(ty).as_u128())), + } + } + /// The function trait that calls the closure, async closure, or `dyn Fn*` that `ty` is, /// or boxes. pub fn owned_fn(&self, ty: Ty<'tcx>) -> Option { @@ -223,8 +232,7 @@ impl<'tcx> Translator<'_, 'tcx> { alias: None, }); let mut methods = Vec::new(); - // `Any`'s object is its class, which a downcast checks for, so it needs no method. - let traits = tcx.supertrait_def_ids(principal).filter(|&tr| !is_any(tcx, tr)); + let traits = tcx.supertrait_def_ids(principal); for trait_ref in traits.flat_map(|tr| refs.iter().filter(move |r| r.def_id == tr)) { let tr = trait_ref.def_id; for &def_id in tcx.own_existential_vtable_entries(tr) { @@ -266,7 +274,8 @@ impl<'tcx> Translator<'_, 'tcx> { self.program.items.push(Item::Union { sym, params: names, - // Any object, as a downcast checks for the class of the value's own type. + // Any object, as a downcast checks for the class of the value's own type, until it + // holds `type_id`. ty: match is_any(tcx, principal) { true => Type::Builtin("object"), false => Type::Object(Vec::new()), @@ -383,11 +392,13 @@ impl<'tcx> Translator<'_, 'tcx> { .filter_map(|m| Some((m.name.clone(), m.ty.clone()?))) .collect(); let classes = object.classes.clone(); + // `dyn Any`'s, which is any object until it holds `type_id`. if let Item::Union { - ty: Type::Object(held), .. + ty: ty @ (Type::Object(_) | Type::Builtin("object")), + .. } = &mut self.program.items[object.item] { - *held = members; + *ty = Type::Object(members); } for (from, held, object) in classes { self.class_method(principal, index, from, held, object, span); @@ -851,14 +862,6 @@ impl<'tcx> Body<'_, '_, 'tcx> { let principal = principal(object).expect("an object's trait"); let methods = &self.t.objects[&principal].methods; let Some(index) = methods.iter().position(|m| m.def_id == def_id) else { - let tcx = self.t.tcx; - if tcx.trait_of_assoc(def_id).is_some_and(|tr| is_any(tcx, tr)) { - let msg = format!( - "`{}` of `{object}`, which is not supported yet", - tcx.def_path_str(def_id) - ); - return self.err(span, msg); - } return self.err( span, format!("`{}` is not a method of `{object}`", self.t.tcx.def_path_str(def_id)), @@ -1171,6 +1174,10 @@ pub fn call<'tcx>( out: &mut Vec, ) -> Result, Vec> { let tcx = b.t.tcx; + // `TypeId::of`, and `Any::type_id` of a type's own impl, which a trait object's class calls. + if let ("TypeId", "of") | ("Any", "type_id") = (owner, name) { + return Ok(Some(b.t.type_id(call.args.type_at(0)))); + } if !matches!( (owner, name), ("dyn Any" | "dyn Error", "is" | "downcast_ref" | "downcast_mut") diff --git a/ts/src/lower/fmt.rs b/ts/src/lower/fmt.rs index 50e6b2ce6..6c94b39b8 100644 --- a/ts/src/lower/fmt.rs +++ b/ts/src/lower/fmt.rs @@ -669,6 +669,7 @@ pub fn std_impl<'tcx>( (Std::Utf8Error, Trait::Display) => rs("utf8ErrorDisplay", vec![value, f]), (Std::Utf8Chunk, Trait::Debug) => rs("utf8ChunkDebug", vec![value, f]), (Std::Duration, Trait::Debug) => Expr::rs("durationDebug", vec![value, f]), + (Std::TypeId, Trait::Debug) => rs("typeIdDebug", vec![value, f]), (Std::Layout, Trait::Debug) => rs("layoutDebug", vec![value, f]), (Std::Location, Trait::Debug) => rs("locationDebug", vec![value, f]), (Std::Location, Trait::Display) => rs("locationDisplay", vec![value, f]), diff --git a/ts/src/lower/library.rs b/ts/src/lower/library.rs index a6f9a1f03..e2c3e46d9 100644 --- a/ts/src/lower/library.rs +++ b/ts/src/lower/library.rs @@ -190,6 +190,9 @@ pub enum Std { BuildHasherDefault, /// `rs.Duration`: its seconds and nanoseconds, never changed once made. Duration, + /// `rs.TypeId`: rustc's 128-bit hash of the type, which std's `TypeId` holds at run time, + /// as 32 hex digits. + TypeId, /// `rs.Layout`: its size and alignment, never changed once made. Layout, /// `rs.Location`: a panic's file, line, and column, never changed once made. @@ -297,6 +300,7 @@ impl Std { } } for (item, std) in [ + (rustc_attr_ir::LangItem::TypeId, Self::TypeId), (rustc_attr_ir::LangItem::UnsafeCell, Self::Cell), (rustc_attr_ir::LangItem::Context, Self::Context), (rustc_attr_ir::LangItem::ResumeTy, Self::Context), diff --git a/ts/src/lower/mir/place.rs b/ts/src/lower/mir/place.rs index f93619b65..5abe05758 100644 --- a/ts/src/lower/mir/place.rs +++ b/ts/src/lower/mir/place.rs @@ -1577,6 +1577,12 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { if let Some(value) = self.cell_value(val, ty, span) { return value; } + if self.b.t.std_of(ty) == Some(Std::TypeId) { + return match self.type_id_const(val, ty) { + Some(of) => self.b.t.type_id(of), + None => self.err(span, format!("a constant of type `{ty}` that names no type")), + }; + } // An aggregate, field by field. if let ty::Adt(..) | ty::Tuple(_) | ty::Array(..) = ty.kind() && !matches!(ty.kind(), ty::Tuple(tys) if tys.is_empty()) @@ -1700,6 +1706,22 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { } } + /// The type the constant `TypeId` `val` is of, which the allocation its first word points + /// into names, as const evaluation writes it. + fn type_id_const(&self, val: ConstValue, ty: Ty<'tcx>) -> Option> { + let tcx = self.tcx; + let id = tcx.try_destructure_mir_constant_for_user_output(val, ty)?; + let &(words, words_ty) = id.fields.first()?; + let words = tcx.try_destructure_mir_constant_for_user_output(words, words_ty)?; + let &(ConstValue::Scalar(Scalar::Ptr(ptr, _)), _) = words.fields.first()? else { + return None; + }; + match tcx.global_alloc(ptr.provenance.alloc_id()) { + GlobalAlloc::TypeId { ty } => Some(ty), + _ => None, + } + } + /// The `Location` of type `ty` at `at` in `alloc`: its file, the `str` another /// allocation holds, and its line and column. fn location_const(&self, alloc: ConstAllocation<'tcx>, at: Size, ty: Ty<'tcx>) -> Option { diff --git a/ts/src/lower/mod.rs b/ts/src/lower/mod.rs index e110030e1..6596c871e 100644 --- a/ts/src/lower/mod.rs +++ b/ts/src/lower/mod.rs @@ -1856,6 +1856,7 @@ impl<'a, 'tcx> Translator<'a, 'tcx> { library::Std::Hasher => Type::Rs("Hasher", vec![]), library::Std::RandomState => Type::Rs("RandomState", vec![]), library::Std::Duration => Type::Rs("Duration", vec![]), + library::Std::TypeId => Type::Rs("TypeId", vec![]), library::Std::Layout => Type::Rs("Layout", vec![]), library::Std::Location => Type::Rs("Location", vec![]), library::Std::PanicHookInfo => Type::Rs("PanicHookInfo", vec![]), diff --git a/ts/src/program.rs b/ts/src/program.rs index 202face44..e7d7baf65 100644 --- a/ts/src/program.rs +++ b/ts/src/program.rs @@ -16,6 +16,7 @@ use crate::ts::{self, FieldId, Function, Item, SymId}; pub const RUNTIME: &[(&str, &str)] = &[ ("rs.ts", include_str!("../runtime/rs.ts")), ("rs/alloc.ts", include_str!("../runtime/rs/alloc.ts")), + ("rs/any.ts", include_str!("../runtime/rs/any.ts")), ("rs/ascii.ts", include_str!("../runtime/rs/ascii.ts")), ("rs/bytes.ts", include_str!("../runtime/rs/bytes.ts")), ("rs/char.ts", include_str!("../runtime/rs/char.ts")), From 91536e80980acbf0f3f4aefc19d11851741e0a78 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 15:33:30 -0800 Subject: [PATCH 03/10] quest: finish quest/m3/ts-dyn.md, as TypeId and Any::type_id translate Co-Authored-By: Claude Opus 5.5 --- quest/m2/ts-model/README.md | 6 +++--- quest/m3/README.md | 1 - quest/m3/ts-dyn.md | 30 ------------------------------ ts/README.md | 6 +++--- ts/fixtures/reject/census.txt | 3 --- ts/fixtures/reject/expected.txt | 3 --- ts/fixtures/reject/src/objects.rs | 5 ----- ts/fixtures/reject/ts.toml | 1 - 8 files changed, 6 insertions(+), 49 deletions(-) delete mode 100644 quest/m3/ts-dyn.md diff --git a/quest/m2/ts-model/README.md b/quest/m2/ts-model/README.md index ff6fcbded..61145f674 100644 --- a/quest/m2/ts-model/README.md +++ b/quest/m2/ts-model/README.md @@ -33,12 +33,12 @@ Decided with the maintainer on 2026-10-27, from a census of the model's 22 publi the translator is specific to moq: dependencies follow general rules, and moq's own changes (safe `cfg` twins of its `unsafe`, dropping or binding `hashlink`, `slab`, and `smallvec`) are one research-tier quest in moq's tree. -- Until `unsafe` and trait objects translate, internal `unsafe` in moq-net and kio gets +- Until `unsafe` translates, internal `unsafe` in moq-net and kio gets safe `cfg` twins in moq, so differential tests cover it, and a dependency containing `unsafe` is bound by the consumer. These are stopgaps: decided with the maintainer on 2026-10-27, a stock crate translates with no annotations or config, so - [unsafe code the translator can model](/quest/m3/ts-unsafe.md) and - [trait objects](/quest/m3/ts-dyn.md) remove them. Only true platform boundaries (clocks and + [unsafe code the translator can model](/quest/m3/ts-unsafe.md) removes them, as trait + objects, which translate, already have. Only true platform boundaries (clocks and DEFLATE) stay bound. - Each child measures this target by the census of `ts/moq/model.toml`, rooted at those types with the boundaries bound, which nightly reports beside the whole crate. diff --git a/quest/m3/README.md b/quest/m3/README.md index d4be3829d..63d6243e5 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -16,7 +16,6 @@ generic std gap is planned here even when moq never calls it. - [Retrial Cranelift on moq's tests](/quest/m3/cranelift-unwind.md) - waits on upstream: moq's tests pass under Cranelift, so its CI can weigh it again - [Relink without rebuilding](/quest/m3/relink.md) - measure upstream's skip of dependency-only rebuilds on moq's edits once it reaches nightly - [Unsafe code the translator can model](/quest/m3/ts-unsafe.md) - a dependency using only `unsafe` the translator can model translates from source -- [Trait objects' TypeId](/quest/m3/ts-dyn.md) - `Any::type_id` and `TypeId` translate with Rust's equality, order, and hash, so a consumer neither rewrites nor binds them - [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 - [rs.Slice](/quest/m3/ts-slice-object.md) - references to arrays of other values are a runtime slice too, and pointers compare by where they point diff --git a/quest/m3/ts-dyn.md b/quest/m3/ts-dyn.md deleted file mode 100644 index 6b4e524ae..000000000 --- a/quest/m3/ts-dyn.md +++ /dev/null @@ -1,30 +0,0 @@ -# [S] Trait objects' TypeId - -## Goal - -[rust2-ts](/ts/README.md) translates `Any::type_id` and `TypeId`, of a trait object and of -`TypeId::of`, with Rust's equality, order, and hash, proven by differential tests -against native Rust, so a consumer neither rewrites nor binds them. - -## Plan - -Trait objects of every other trait translate, std's and mapped crates' included, each -std type's class calling the mapping of its impl. Decided with the maintainer on -2026-10-27: a stock crate translates with no annotations or config, so trait objects move -from never to not yet. - -`TypeId` has no JS value yet: the class of the value's own type stands for its type in a -downcast, but `TypeId::of` of a type no object holds has none, and a `&mut dyn Any` of a -value JS copies is of a second class. Decided with the maintainer on 2026-11-04: - -- ✅ rustc's 128-bit `type_id_hash` of the type, which std's `TypeId` holds at run time; - each object's class returns its type's as a constant. Its traits are std's `TypeId` - impls, not `u128`'s: `Hash` writes one `u64`, `Debug` prints `TypeId(0x…)`, and `Ord` - is derived over its words, so a test logs a `Hasher`'s calls and checks order and - `Debug`'s shape. Its value is native's only where the crate's metadata hash is, so tests - compare within a run rather than the exact bits. -- Rejected: the type's path as a string, whose order and `Debug` are not native's; the - class itself, which still needs a value for order and hash, and a class for a type no - object holds. - -Public API: the translator's output. diff --git a/ts/README.md b/ts/README.md index 12744f599..c14b07eef 100644 --- a/ts/README.md +++ b/ts/README.md @@ -1080,9 +1080,9 @@ they need. ## Not yet Byte reinterpretation, pointer addresses, pointer arithmetic on a value JS keeps as an object (other than wrapping arithmetic on a null or dangling pointer), memory from `alloc` other than an array of values JS copies, and unions whose -fields overlap in different types ([unsafe](/quest/m3/ts-unsafe.md)), and trait objects other than -`dyn Debug`, `dyn Display`, `dyn Future`, `dyn Any`, `dyn Error`, `dyn Fn*`, `dyn Buf`, `dyn Iterator` and its subtraits, and the translated crates' traits' -behind `&`, `&mut`, `Box`, `Arc`, `Rc`, `Weak`, or `Pin` ([trait objects](/quest/m3/ts-dyn.md)), fail translation. Until they translate, an item that needs one, such as a `Box` made `From` a string, binds to +fields overlap in different types ([unsafe](/quest/m3/ts-unsafe.md)), and trait objects of a trait +with a const parameter, of an array, or behind a pointer other than `&`, `&mut`, `Box`, `Arc`, `Rc`, +`Weak`, or `Pin`, fail translation. Until they translate, an item that needs one, such as a `Box` made `From` a string, binds to hand-written TS ([bindings](#bindings)). These fail translation: `f16` and `f128`, a `Poll` of a `Poll` of a `Poll`, a future whose output can be pending, an instance of a generic type whose field is a `Poll` of a type parameter that can be pending, a closure that owns a value diff --git a/ts/fixtures/reject/census.txt b/ts/fixtures/reject/census.txt index 8c74743d0..447a5d160 100644 --- a/ts/fixtures/reject/census.txt +++ b/ts/fixtures/reject/census.txt @@ -101,9 +101,6 @@ fixtures/reject/src/keys.rs:place_bounds+1:9: unsupported call to `std::ops::Ran fixtures/reject/src/keys.rs:places_sorted+1:15: unsupported call to ` as std::iter::Iterator>::is_sorted` fixtures/reject/src/keys.rs:set_keys+1:75: comparing `std::collections::BTreeSet` as a key, which is not supported yet fixtures/reject/src/keys.rs:set_keys+1:75: hashing `std::collections::BTreeSet` as a key, which is not supported yet -fixtures/reject/src/objects.rs:any_type_id+1:2: unsupported call to `::eq` -fixtures/reject/src/objects.rs:any_type_id+1:4: `std::any::Any::type_id` of `dyn std::any::Any`, which is not supported yet -fixtures/reject/src/objects.rs:any_type_id+1:17: unsupported call to `std::any::TypeId::of::` fixtures/reject/src/objects.rs:array_object+1:2: a trait object of `[u16; 2]`, which is not supported yet fixtures/reject/src/objects.rs:dyn_compared+3:2: comparing pointers to `dyn objects::Reading`, each an object JS makes of its own as it unsizes fixtures/reject/src/objects.rs:dyn_size+1:2: unsupported call to `std::mem::size_of_val::` diff --git a/ts/fixtures/reject/expected.txt b/ts/fixtures/reject/expected.txt index b3b900074..1ad614d6b 100644 --- a/ts/fixtures/reject/expected.txt +++ b/ts/fixtures/reject/expected.txt @@ -103,9 +103,6 @@ fixtures/reject/src/keys.rs:place_bounds+1:9: unsupported call to `std::ops::Ran fixtures/reject/src/keys.rs:places_sorted+1:15: unsupported call to ` as std::iter::Iterator>::is_sorted` fixtures/reject/src/keys.rs:set_keys+1:75: comparing `std::collections::BTreeSet` as a key, which is not supported yet fixtures/reject/src/keys.rs:set_keys+1:75: hashing `std::collections::BTreeSet` as a key, which is not supported yet -fixtures/reject/src/objects.rs:any_type_id+1:2: unsupported call to `::eq` -fixtures/reject/src/objects.rs:any_type_id+1:4: `std::any::Any::type_id` of `dyn std::any::Any`, which is not supported yet -fixtures/reject/src/objects.rs:any_type_id+1:17: unsupported call to `std::any::TypeId::of::` fixtures/reject/src/objects.rs:array_object+1:2: a trait object of `[u16; 2]`, which is not supported yet fixtures/reject/src/objects.rs:dyn_compared+3:2: comparing pointers to `dyn objects::Reading`, each an object JS makes of its own as it unsizes fixtures/reject/src/objects.rs:dyn_size+1:2: unsupported call to `std::mem::size_of_val::` diff --git a/ts/fixtures/reject/src/objects.rs b/ts/fixtures/reject/src/objects.rs index af0502431..d2211523a 100644 --- a/ts/fixtures/reject/src/objects.rs +++ b/ts/fixtures/reject/src/objects.rs @@ -143,11 +143,6 @@ pub fn same_named(x: &u8) -> u8 { a.name().wrapping_add(b.name()) } -/// A `TypeId`, which no value stands for yet. -pub fn any_type_id(a: &dyn std::any::Any) -> bool { - a.type_id() == std::any::TypeId::of::() -} - pub trait Source { type Item: Reading; fn item(&self) -> &Self::Item; diff --git a/ts/fixtures/reject/ts.toml b/ts/fixtures/reject/ts.toml index c3659bf03..8e625151c 100644 --- a/ts/fixtures/reject/ts.toml +++ b/ts/fixtures/reject/ts.toml @@ -81,7 +81,6 @@ roots = [ "keys::set_keys", "lopsided", "missing", - "objects::any_type_id", "objects::array_object", "objects::dyn_compared", "objects::dyn_size", From baa4c93c3ddaa1aaaccc0ff6cb16f3e3443f4fbc Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:30:13 -0800 Subject: [PATCH 04/10] fix(ts): write TypeId's Debug in std's sequence of writes Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/lang/dyns/src/ids.rs | 49 ++++++++++++++++++++++++++++++++ ts/runtime/rs/any.ts | 13 +++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/ts/fixtures/lang/dyns/src/ids.rs b/ts/fixtures/lang/dyns/src/ids.rs index 52c513a17..d51c6cedd 100644 --- a/ts/fixtures/lang/dyns/src/ids.rs +++ b/ts/fixtures/lang/dyns/src/ids.rs @@ -9,6 +9,7 @@ use std::any::{Any, TypeId}; use std::collections::{BTreeSet, HashMap, HashSet}; +use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::rc::Rc; @@ -67,6 +68,34 @@ impl Hasher for Log { } } +/// Takes at most `cap` bytes, logging each `write_str` it takes, and fails the call that +/// would pass `cap`. +struct Capped { + log: Vec, + len: usize, + calls: usize, + cap: usize, +} + +impl Write for Capped { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.calls += 1; + if self.len + s.len() > self.cap { + return Err(fmt::Error); + } + self.len += s.len(); + self.log.push(s.to_string()); + Ok(()) + } +} + +/// `id`'s `Debug`, written into a `Capped` of `cap` bytes. +fn capped(id: TypeId, cap: usize) -> (fmt::Result, Capped) { + let mut w = Capped { log: Vec::new(), len: 0, calls: 0, cap }; + let result = write!(w, "{id:?}"); + (result, w) +} + /// A `TypeId` the compiler evaluates. const U8: TypeId = TypeId::of::(); @@ -214,6 +243,26 @@ pub fn ids(data: &[u8], out: &mut Vec) { ); let (x, y) = (ids[usize::from(a) % ids.len()], ids[usize::from(b) % ids.len()]); put(out, &format!("{} ", ids.iter().all(|&id| hash_of(id).is_some()))); + // `Debug` writes as std's `write!` does: `TypeId(`, `0x`, a `write_char` of each leading + // zero, the digits, and `)`, stopping at the first write the writer fails. + let (result, w) = capped(x, usize::from(a % 10)); + put(out, &format!("{result:?} {} {:?} ", w.calls, w.log)); + let debug = format!("{x:?}"); + let zeros = debug[9..].bytes().take_while(|&b| b == b'0').count().min(31); + let (result, w) = capped(x, usize::MAX); + let (digits, n) = (&w.log[2..w.log.len() - 1], w.log.len()); + put( + out, + &format!( + "{result:?} {:?} {:?} {} {} ", + &w.log[..2], + w.log.last(), + n == 4 + zeros && digits[..zeros].iter().all(|d| d == "0"), + digits.concat() == debug[9..41], + ), + ); + let (result, w) = capped(x, debug.len() - 1); + put(out, &format!("{result:?} {} ", w.log.concat() + ")" == debug)); let mut log = Log::default(); x.hash(&mut log); let high = hash_of(x).map(|h| format!("u64 {:x}", h >> 64)); diff --git a/ts/runtime/rs/any.ts b/ts/runtime/rs/any.ts index d55f35978..13be31976 100644 --- a/ts/runtime/rs/any.ts +++ b/ts/runtime/rs/any.ts @@ -1,6 +1,6 @@ // `core::any::TypeId`, for rust2-ts output. `rs.ts` re-exports all of it. -import { type FmtResult, type Formatter, fmtWriteStr } from "../rs.ts"; +import { type FmtResult, type Formatter, fmtPadIntegral, fmtSpec, fmtWriteFmt, type Spec } from "../rs.ts"; import { cmpStr, type Ordering } from "./collections.ts"; import { type Hasher, hash64 } from "./hash.ts"; import { u64FromHalves } from "./int.ts"; @@ -28,7 +28,14 @@ export function typeIdHash(id: TypeId, s: Hasher): void { hash64(u64FromHalves(parseInt(id.slice(0, 8), 16), parseInt(id.slice(8, 16), 16)), s); } -/** `Debug`, as std's: `TypeId(0x…)` of the hash's 32 digits, which no width pads. */ +/** + * `Debug`, as std's `write!(f, "TypeId({:#034x})", ..)`: `TypeId(`, `0x`, a zero for each + * leading zero digit, the rest, and `)`, each its own write. + */ export function fmtTypeIdDebug(id: TypeId, f: Formatter): FmtResult { - return fmtWriteStr(f, `TypeId(0x${id})`); + const digits = id.replace(/^0+(?=.)/, ""); + return fmtWriteFmt(f, ["TypeId(", fmtSpec(HASH, (g) => fmtPadIntegral(g, true, "0x", digits)), ")"]); } + +/** `{:#034x}`. */ +const HASH: Spec = { alternate: true, zero: true, width: 34 }; From a57134e51214b9af06602f4250224d3071c4146a Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:43:31 -0800 Subject: [PATCH 05/10] test(ts): snapshot TypeId Debug's capped-writer case Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/lang/dyns/expected/ids.Capped.ts | 27 +++ ts/fixtures/lang/dyns/expected/ids.ts | 165 ++++++++++++------- 2 files changed, 133 insertions(+), 59 deletions(-) create mode 100644 ts/fixtures/lang/dyns/expected/ids.Capped.ts diff --git a/ts/fixtures/lang/dyns/expected/ids.Capped.ts b/ts/fixtures/lang/dyns/expected/ids.Capped.ts new file mode 100644 index 000000000..926cb56d3 --- /dev/null +++ b/ts/fixtures/lang/dyns/expected/ids.Capped.ts @@ -0,0 +1,27 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; + +/** + * Takes at most `cap` bytes, logging each `write_str` it takes, and fails the call that + * would pass `cap`. + */ +export interface Capped { + log: rs.Vec; + len: rs.usize; + calls: rs.usize; + cap: rs.usize; +} + +export function writeStr$fmt_Write(self: Capped, s: string): rs.Result { + self.calls = rs.usizeAdd(self.calls, 1); + if (!(rs.usizeAdd(self.len, rs.stringLen(s)) > self.cap)) { + const _10: rs.usize = rs.stringLen(s); + self.len = rs.usizeAdd(self.len, _10); + self.log.items.push(s); + return rs.OK; + } + return rs.Err(new rs.FmtError()); +} + +//# sourceMappingURL=ids.Capped.ts.map diff --git a/ts/fixtures/lang/dyns/expected/ids.ts b/ts/fixtures/lang/dyns/expected/ids.ts index 388d0e72c..c9bbd9cd2 100644 --- a/ts/fixtures/lang/dyns/expected/ids.ts +++ b/ts/fixtures/lang/dyns/expected/ids.ts @@ -8,6 +8,7 @@ import { unwrapOrDefault$15dio94 as option_unwrapOrDefault$15dio94, map$1tqulv0 import { ok$03r6cuf } from "./core/result.ts"; import { put } from "./harness.ts"; import type * as Byte from "./ids.Byte.ts"; +import * as Capped from "./ids.Capped.ts"; import * as Log from "./ids.Log.ts"; import type * as Marked from "./ids.Marked.ts"; import type * as Mood from "./ids.Mood.ts"; @@ -17,6 +18,13 @@ export function tag$ids_Marked_u8(self: rs.u8): rs.u8 { return self; } +/** `id`'s `Debug`, written into a `Capped` of `cap` bytes. */ +export function capped(id: rs.TypeId, cap: rs.usize): [rs.Result, Capped.Capped] { + const w: Capped.Capped = { log: new rs.Vec(), len: 0, calls: 0, cap }; + const args3 = [(f: rs.Formatter) => rs.fmtTypeIdDebug(id, f)]; + return [rs.fmtWrite((s) => Capped.writeStr$fmt_Write(w, s), (c) => Capped.writeStr$fmt_Write(w, String.fromCodePoint(c)), [args3[0]]), w] as [rs.Result, Capped.Capped]; +} + /** `T`'s `TypeId`, through a type parameter. */ export function idOf$Option_u8(): rs.TypeId { return "3801bd64778907c7633cf473fe556a70"; @@ -90,8 +98,9 @@ export function words(id: rs.TypeId): rs.Vec { export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, out: rs.ByteVec): void { let mood!: Mood.Mood; let _196!: Any.Any; - let _392!: rs.TypeId; - const _486: (a0: WithId.WithId, a1: WithId.WithId) => rs.Ordering = (k: WithId.WithId, l: WithId.WithId): rs.Ordering => { + let _420!: boolean; + let _515!: rs.TypeId; + const _609: (a0: WithId.WithId, a1: WithId.WithId) => rs.Ordering = (k: WithId.WithId, l: WithId.WithId): rs.Ordering => { const _62: rs.Vec = words(k.id); const _9: rs.Vec = words(l.id); return rs.orderingThen(rs.cmpSlice(rs.cmp)(_62, _9), rs.cmp(k.n, l.n)); @@ -156,8 +165,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou }); const _168: boolean = _146.typeId$Any() === any.typeId$Any(); const _174: boolean = idOfVal$dyn_ids_Marked(_146) === "21b3f780835871567b1dbe5c04134c71"; - const args32 = [(f: rs.Formatter) => rs.u8Display(_159, f), (f: rs.Formatter) => rs.fmtOption(_161, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_168, f), (f: rs.Formatter) => rs.fmtBool(_174, f)]; - put(out, rs.fmtFormat([args32[0], " ", args32[1], " ", args32[2], " ", args32[3], " "])); + const args40 = [(f: rs.Formatter) => rs.u8Display(_159, f), (f: rs.Formatter) => rs.fmtOption(_161, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_168, f), (f: rs.Formatter) => rs.fmtBool(_174, f)]; + put(out, rs.fmtFormat([args40[0], " ", args40[1], " ", args40[2], " ", args40[3], " "])); } const boxes: rs.Vec = new rs.Vec(); for (const x of rs.byteSliceView(new rs.ByteSlice(dataData, dataStart + 2, dataLen - 2))) { @@ -177,8 +186,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou return i5 === inner; }); const _229: boolean = "37a732caafaf8e089d3a9d4c07b2ec78" === "37a732caafaf8e089d3a9d4c07b2ec78"; - const args33 = [(f: rs.Formatter) => rs.fmtOption(_221, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_229, f)]; - put(out, rs.fmtFormat([args33[0], " ", args33[1], " "])); + const args41 = [(f: rs.Formatter) => rs.fmtOption(_221, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_229, f)]; + put(out, rs.fmtFormat([args41[0], " ", args41[1], " "])); } const _240: rs.Arc = new rs.Arc(byte); const shared: rs.Arc = new rs.ArcDyn(_240, new of$ids_Byte(_240.value)); @@ -186,8 +195,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _251: boolean = shared.value.typeId$Any() === "2dfe447c5824b47a6710c76af5f599c5"; const _259: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; const _266: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; - const args34 = [(f: rs.Formatter) => rs.fmtBool(_251, f), (f: rs.Formatter) => rs.fmtBool(_259, f), (f: rs.Formatter) => rs.fmtBool(_266, f)]; - put(out, rs.fmtFormat([args34[0], " ", args34[1], " ", args34[2], " "])); + const args42 = [(f: rs.Formatter) => rs.fmtBool(_251, f), (f: rs.Formatter) => rs.fmtBool(_259, f), (f: rs.Formatter) => rs.fmtBool(_266, f)]; + put(out, rs.fmtFormat([args42[0], " ", args42[1], " ", args42[2], " "])); const _279: rs.Slice = rs.sliceFrom(ids); const pairs: () => rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> = (): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { return rs.iterFlatMap(rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_279))), (_210: [rs.usize, rs.TypeId]): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { @@ -222,18 +231,18 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _298: boolean = rs.iterAll(pairs(), (_215: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { const x6: rs.TypeId = _215[1]; const y5: rs.TypeId = _215[3]; - const _611: rs.Ordering | undefined = rs.typeIdCmp(x6, y5); + const _619: rs.Ordering | undefined = rs.typeIdCmp(x6, y5); const _134: rs.Vec = words(x6); const _157: rs.Vec = words(y5); - return _611 === rs.cmpSlice(rs.cmp)(_134, _157) as rs.Ordering | undefined; + return _619 === rs.cmpSlice(rs.cmp)(_134, _157) as rs.Ordering | undefined; }); const _303: boolean = rs.iterAll(pairs(), (_219: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { const x7: rs.TypeId = _219[1]; const y6: rs.TypeId = _219[3]; - const _612: boolean = rs.typeIdCmp(x7, y6) === -1; + const _620: boolean = rs.typeIdCmp(x7, y6) === -1; const _1112: rs.Vec = words(x7); const _139: rs.Vec = words(y6); - if (!(_612 === (rs.cmpSlice(rs.cmp)(_1112, _139) === -1))) { + if (!(_620 === (rs.cmpSlice(rs.cmp)(_1112, _139) === -1))) { return false; } const order2 = rs.typeIdCmp(x7, y6); @@ -243,8 +252,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const order3 = rs.cmpSlice(rs.cmp)(_192, _2110); return _145 === (order3 !== undefined && order3 >= 0); }); - const args35 = [(f: rs.Formatter) => rs.fmtBool(_288, f), (f: rs.Formatter) => rs.fmtBool(_293, f), (f: rs.Formatter) => rs.fmtBool(_298, f), (f: rs.Formatter) => rs.fmtBool(_303, f)]; - put(out, rs.fmtFormat([args35[0], " ", args35[1], " ", args35[2], " ", args35[3], " "])); + const args43 = [(f: rs.Formatter) => rs.fmtBool(_288, f), (f: rs.Formatter) => rs.fmtBool(_293, f), (f: rs.Formatter) => rs.fmtBool(_298, f), (f: rs.Formatter) => rs.fmtBool(_303, f)]; + put(out, rs.fmtFormat([args43[0], " ", args43[1], " ", args43[2], " ", args43[3], " "])); const _318: rs.usize = rs.usizeRem(a as rs.usize, rs.sliceFrom(ids).length); if (!(_318 < 13)) { rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _318); @@ -261,67 +270,105 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou return hashOf(_220) !== undefined; }); put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(part4, f), " "])); + const _352: [rs.Result, Capped.Capped] = capped(x2, rs.u8Rem(a, 10) as rs.usize); + const result: rs.Result = _352[0]; + const w: Capped.Capped = _352[1]; + const _367: rs.Fmt = (f: rs.Formatter) => rs.fmtResult(result, f, rs.fmtUnit, rs.fmtErrorDebug); + const arg = w.calls; + const _368: rs.Fmt = (f: rs.Formatter) => rs.usizeDisplay(arg, f); + const arg2 = w.log; + const args45 = [_367, _368, (f: rs.Formatter) => rs.fmtList(arg2.items, f, rs.fmtStr)]; + put(out, rs.fmtFormat([args45[0], " ", args45[1], " ", args45[2], " "])); + const debug: string = rs.fmtFormat([(f: rs.Formatter) => rs.fmtTypeIdDebug(x2, f)]); + const zeros: rs.usize = rs.min(rs.iterCount(rs.iterTakeWhile(rs.strBytes(rs.strSlice(debug, 9)), (_222: rs.u8): boolean => { + return _222 === 48; + })), 31); + const _390: [rs.Result, Capped.Capped] = capped(x2, 4294967295); + const result2: rs.Result = _390[0]; + const w2: Capped.Capped = _390[1]; + const part5 = rs.usizeSub(w2.log.items.length, 1); + const _394: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 2, part5); + const n2: rs.usize = w2.log.items.length; + const _412: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 0, 2); + const _416: string | undefined = rs.sliceLast(rs.sliceFrom(w2.log.items)); + if (!(n2 === rs.usizeAdd(4, zeros))) { + _420 = false; + } else { + _420 = rs.iterAll(rs.iterSlice(rs.sliceItems(rs.sliceRange(_394, 0, zeros))), (d: string): boolean => { + return d === "0"; + }); + } + const _419: boolean = _420; + const _429: boolean = rs.strsJoin(rs.sliceItems(_394), "") === rs.strSlice(debug, 9, 41); + const args47 = [(f: rs.Formatter) => rs.fmtResult(result2, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtList(rs.sliceItems(_412), f, rs.fmtStr), (f: rs.Formatter) => rs.fmtOption(_416, f, rs.fmtStr), (f: rs.Formatter) => rs.fmtBool(_419, f), (f: rs.Formatter) => rs.fmtBool(_429, f)]; + put(out, rs.fmtFormat([args47[0], " ", args47[1], " ", args47[2], " ", args47[3], " ", args47[4], " "])); + const _447: rs.usize = rs.usizeSub(rs.stringLen(debug), 1); + const _446: [rs.Result, Capped.Capped] = capped(x2, _447); + const result3: rs.Result = _446[0]; + const _459: boolean = rs.strsJoin(_446[1].log.items, "") + ")" === debug; + const args48 = [(f: rs.Formatter) => rs.fmtResult(result3, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtBool(_459, f)]; + put(out, rs.fmtFormat([args48[0], " ", args48[1], " "])); const log: Log.Log = Log.default$Default(); rs.typeIdHash(x2, new rs.OwnHasher(log, Log.hasher$hash_Hasher)); const high: string | undefined = option_map$1tqulv0(hashOf(x2), (h: rs.u128): string => { - const part5 = rs.u128Shr(h, 64); - return rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u128LowerHex(part5, f)]); + const part6 = rs.u128Shr(h, 64); + return rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u128LowerHex(part6, f)]); }); - const _364: rs.usize = log._0.items.length; - const _367: boolean = rs.sliceFirst(rs.sliceFrom(log._0.items)) === high; - const args40 = [(f: rs.Formatter) => rs.usizeDisplay(_364, f), (f: rs.Formatter) => rs.fmtBool(_367, f)]; - put(out, rs.fmtFormat([args40[0], " ", args40[1], " "])); - const _390: rs.TypeId = rs.ordMax(x2, y, rs.cmpLt(rs.typeIdCmp)); - const _395: rs.Vec = words(x2); - const _397: rs.Vec = words(y); - if (!(rs.cmpSlice(rs.cmp)(_395, _397) === -1)) { - _392 = x2; + const _487: rs.usize = log._0.items.length; + const _490: boolean = rs.sliceFirst(rs.sliceFrom(log._0.items)) === high; + const args52 = [(f: rs.Formatter) => rs.usizeDisplay(_487, f), (f: rs.Formatter) => rs.fmtBool(_490, f)]; + put(out, rs.fmtFormat([args52[0], " ", args52[1], " "])); + const _513: rs.TypeId = rs.ordMax(x2, y, rs.cmpLt(rs.typeIdCmp)); + const _518: rs.Vec = words(x2); + const _520: rs.Vec = words(y); + if (!(rs.cmpSlice(rs.cmp)(_518, _520) === -1)) { + _515 = x2; } else { - _392 = y; + _515 = y; } - const arg = _390 === _392; - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(arg, f), " "])); + const arg3 = _513 === _515; + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(arg3, f), " "])); const sorted: rs.Vec = rs.vecFrom(ids.slice()); rs.sliceSort(rs.sliceFrom(sorted.items), rs.cmpLt(rs.typeIdCmp), 16, true); - const ordered: boolean = rs.iterAll(rs.sliceWindows(rs.sliceFrom(sorted.items), 2), (w: rs.Slice): boolean => { - rs.idx(w, 0); - const _429: rs.Vec = words(w.data[w.start]); - rs.idx(w, 1); - const _1011: rs.Vec = words(w.data[w.start + 1]); - return rs.cmpSlice(rs.cmp)(_429, _1011) === -1; + const ordered: boolean = rs.iterAll(rs.sliceWindows(rs.sliceFrom(sorted.items), 2), (w4: rs.Slice): boolean => { + rs.idx(w4, 0); + const _424: rs.Vec = words(w4.data[w4.start]); + rs.idx(w4, 1); + const _1011: rs.Vec = words(w4.data[w4.start + 1]); + return rs.cmpSlice(rs.cmp)(_424, _1011) === -1; }); - const _414: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); - const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.typeIdCmp) as rs.BTreeSet, _414, true, undefined, undefined, 16, true); - const _421: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); - const hashed: rs.HashSet = rs.hashExtendKeys(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashSet, _421, undefined, undefined, 58720256); - const _435: rs.usize = rs.btreeLen(set); - const _438: rs.usize = rs.hashLen(hashed); - const args42 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_435, f), (f: rs.Formatter) => rs.usizeDisplay(_438, f)]; - put(out, rs.fmtFormat([args42[0], " ", args42[1], " ", args42[2], " "])); - const _448: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["2dfe447c5824b47a6710c76af5f599c5", "byte"] as [rs.TypeId, string], ["ff641c451ae80e5aeea189eeac47965a", "mood"] as [rs.TypeId, string]]); - const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _448, undefined, undefined, undefined, 58720256); - for (const _461 of boxes.items) { - const part6 = rs.hashGet(names, _461.typeId$Any()); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part6, f, rs.fmtStr), " "])); + const _537: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.typeIdCmp) as rs.BTreeSet, _537, true, undefined, undefined, 16, true); + const _544: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const hashed: rs.HashSet = rs.hashExtendKeys(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashSet, _544, undefined, undefined, 58720256); + const _558: rs.usize = rs.btreeLen(set); + const _561: rs.usize = rs.hashLen(hashed); + const args54 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_558, f), (f: rs.Formatter) => rs.usizeDisplay(_561, f)]; + put(out, rs.fmtFormat([args54[0], " ", args54[1], " ", args54[2], " "])); + const _571: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["2dfe447c5824b47a6710c76af5f599c5", "byte"] as [rs.TypeId, string], ["ff641c451ae80e5aeea189eeac47965a", "mood"] as [rs.TypeId, string]]); + const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _571, undefined, undefined, undefined, 58720256); + for (const _584 of boxes.items) { + const part7 = rs.hashGet(names, _584.typeId$Any()); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part7, f, rs.fmtStr), " "])); } const keys: WithId.WithId[] = [{ id: x2, n: a }, { id: y, n: b }, { id: x2, n: b }]; - const _494: rs.Slice = rs.sliceFrom(keys); - const part9 = rs.iterToVec(rs.iterMap(rs.iterFlatMap(rs.iterSlice(keys), (k2: WithId.WithId): rs.Iter<[WithId.WithId, WithId.WithId]> => { - return rs.iterMap(rs.iterSlice(rs.sliceItems(_494)), (l2: WithId.WithId): [WithId.WithId, WithId.WithId] => { + const _617: rs.Slice = rs.sliceFrom(keys); + const part10 = rs.iterToVec(rs.iterMap(rs.iterFlatMap(rs.iterSlice(keys), (k2: WithId.WithId): rs.Iter<[WithId.WithId, WithId.WithId]> => { + return rs.iterMap(rs.iterSlice(rs.sliceItems(_617)), (l2: WithId.WithId): [WithId.WithId, WithId.WithId] => { return [k2, l2] as [WithId.WithId, WithId.WithId]; }); - }, undefined, true), (_222: [WithId.WithId, WithId.WithId]): [boolean, boolean] => { - const k3: WithId.WithId = _222[0]; - const l3: WithId.WithId = _222[1]; - return [WithId.eq$cmp_PartialEq(k3, l3), WithId.cmp$cmp_Ord(k3, l3) === _486(k3, l3)] as [boolean, boolean]; + }, undefined, true), (_227: [WithId.WithId, WithId.WithId]): [boolean, boolean] => { + const k3: WithId.WithId = _227[0]; + const l3: WithId.WithId = _227[1]; + return [WithId.eq$cmp_PartialEq(k3, l3), WithId.cmp$cmp_Ord(k3, l3) === _609(k3, l3)] as [boolean, boolean]; }), "next", 2); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(part9.items, f, (value: [boolean, boolean], f: rs.Formatter) => rs.fmtTuple([(f: rs.Formatter) => rs.fmtBool(value[0], f), (f: rs.Formatter) => rs.fmtBool(value[1], f)], f)), " "])); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(part10.items, f, (value: [boolean, boolean], f: rs.Formatter) => rs.fmtTuple([(f: rs.Formatter) => rs.fmtBool(value[0], f), (f: rs.Formatter) => rs.fmtBool(value[1], f)], f)), " "])); const log2: Log.Log = Log.default$Default(); WithId.hash$Hash_ids_Log(keys[0], log2); - const _523: rs.usize = log2._0.items.length; - const _526: string | undefined = rs.sliceGet(rs.sliceFrom(log2._0.items), 1); - const args45 = [(f: rs.Formatter) => rs.usizeDisplay(_523, f), (f: rs.Formatter) => rs.fmtOption(_526, f, rs.fmtStr)]; - put(out, rs.fmtFormat([args45[0], " ", args45[1]])); + const _646: rs.usize = log2._0.items.length; + const _649: string | undefined = rs.sliceGet(rs.sliceFrom(log2._0.items), 1); + const args57 = [(f: rs.Formatter) => rs.usizeDisplay(_646, f), (f: rs.Formatter) => rs.fmtOption(_649, f, rs.fmtStr)]; + put(out, rs.fmtFormat([args57[0], " ", args57[1]])); rs.drop(boxed); shared[Symbol.dispose](); rs.dropVec(boxes); From 862ded0f542312e3c1b00d92b7ea91a5ff0b5df3 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:44:25 -0800 Subject: [PATCH 06/10] quest(m3): drop the spike's link to the finished ts-dyn quest Co-Authored-By: Claude Opus 5.5 --- quest/m3/ts-wasm-bindgen/spike.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quest/m3/ts-wasm-bindgen/spike.md b/quest/m3/ts-wasm-bindgen/spike.md index 98c886e32..287876e81 100644 --- a/quest/m3/ts-wasm-bindgen/spike.md +++ b/quest/m3/ts-wasm-bindgen/spike.md @@ -26,7 +26,7 @@ It also answers, for the imports quest: - How a mapped `JsValue`, `JsCast`, and `Closure` meet the generic code around them, such as `Closure::new` of a closure, which web-codecs' output and error callbacks need, given - that [trait objects](/quest/m3/ts-dyn.md) other than `TypeId` already translate. + that trait objects, `TypeId` included, already translate. - How the differential test's native side runs a wasm-bindgen build: the wasm-bindgen CLI in the dev shell at the fixture's pinned version, and a host with WebCodecs, which Bun lacks, so likely a headless browser. From 3d7e6ea95b13c11ad2bec641e2b1615b1d7e8629 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:49:40 -0800 Subject: [PATCH 07/10] style(ts): format the TypeId capped-writer case Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/lang/dyns/src/ids.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ts/fixtures/lang/dyns/src/ids.rs b/ts/fixtures/lang/dyns/src/ids.rs index d51c6cedd..7665eaf39 100644 --- a/ts/fixtures/lang/dyns/src/ids.rs +++ b/ts/fixtures/lang/dyns/src/ids.rs @@ -91,7 +91,12 @@ impl Write for Capped { /// `id`'s `Debug`, written into a `Capped` of `cap` bytes. fn capped(id: TypeId, cap: usize) -> (fmt::Result, Capped) { - let mut w = Capped { log: Vec::new(), len: 0, calls: 0, cap }; + let mut w = Capped { + log: Vec::new(), + len: 0, + calls: 0, + cap, + }; let result = write!(w, "{id:?}"); (result, w) } From 0b5b60f92311414ec38f174ab6c395eacccaa884 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Fri, 6 Nov 2026 20:19:35 -0800 Subject: [PATCH 08/10] fix(ts): a TypeId constant behind a reference, and a hook payload's type A `&TypeId` constant, or a reference to one, reads the `TypeId` from the memory it points into, rather than refusing a pointer into memory. `rs.hookPayload` returns the payload classes' type, so a hook can call `type_id` on its payload and type-check. Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/lang/dyns/expected/ids.ts | 338 +++++++++--------- ts/fixtures/lang/dyns/src/ids.rs | 5 + .../lang/panics/hook/expected/core/any.Any.ts | 4 +- .../lang/panics/hook/expected/hooked.ts | 30 +- ts/fixtures/lang/panics/hook/expected/lib.ts | 36 +- ts/fixtures/lang/panics/src/hooked.rs | 2 +- ts/runtime/rs/hook.ts | 5 +- ts/src/lower/mir/place.rs | 8 + 8 files changed, 236 insertions(+), 192 deletions(-) diff --git a/ts/fixtures/lang/dyns/expected/ids.ts b/ts/fixtures/lang/dyns/expected/ids.ts index c9bbd9cd2..392a94b90 100644 --- a/ts/fixtures/lang/dyns/expected/ids.ts +++ b/ts/fixtures/lang/dyns/expected/ids.ts @@ -42,12 +42,12 @@ export function idOfVal$dyn_Any(_1: Any.Any): rs.TypeId { /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$dyn_ids_Marked(_1: Marked.Marked): rs.TypeId { - return "21b3f780835871567b1dbe5c04134c71"; + return "25e58479a985a0390f094b8a47a772ec"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$ids_Mood(_1: Mood.Mood): rs.TypeId { - return "ff641c451ae80e5aeea189eeac47965a"; + return "180954c559d9dbe8afcd63c1da176c31"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ @@ -97,13 +97,13 @@ export function words(id: rs.TypeId): rs.Vec { export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, out: rs.ByteVec): void { let mood!: Mood.Mood; - let _196!: Any.Any; - let _420!: boolean; - let _515!: rs.TypeId; - const _609: (a0: WithId.WithId, a1: WithId.WithId) => rs.Ordering = (k: WithId.WithId, l: WithId.WithId): rs.Ordering => { - const _62: rs.Vec = words(k.id); + let _215!: Any.Any; + let _439!: boolean; + let _534!: rs.TypeId; + const _628: (a0: WithId.WithId, a1: WithId.WithId) => rs.Ordering = (k: WithId.WithId, l: WithId.WithId): rs.Ordering => { + const _63: rs.Vec = words(k.id); const _9: rs.Vec = words(l.id); - return rs.orderingThen(rs.cmpSlice(rs.cmp)(_62, _9), rs.cmp(k.n, l.n)); + return rs.orderingThen(rs.cmpSlice(rs.cmp)(_63, _9), rs.cmp(k.n, l.n)); }; if (dataLen >= 2) { const _10: [rs.u8, rs.u8] = [dataData[dataStart], dataData[dataStart + 1]]; @@ -116,259 +116,263 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou mood = "Calm" as Mood.Mood; } const byte: Byte.Byte = { _0: b }; - const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "2dfe447c5824b47a6710c76af5f599c5", "ff641c451ae80e5aeea189eeac47965a", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "21b3f780835871567b1dbe5c04134c71", "25ff997ce0b3a76fb5ce30b55accc57f"]; - const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "2dfe447c5824b47a6710c76af5f599c5", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "2dfe447c5824b47a6710c76af5f599c5", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; + const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "eb8e0be2af5c781063b1d1468b15a0f1", "180954c559d9dbe8afcd63c1da176c31", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "25e58479a985a0390f094b8a47a772ec", "25ff997ce0b3a76fb5ce30b55accc57f"]; + const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "cfb1622e7734f8af272d8d182905dc25", "eb8e0be2af5c781063b1d1468b15a0f1", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "eb8e0be2af5c781063b1d1468b15a0f1", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; const iter: rs.Iter = rs.iterSlice(found); while (true) { - const _51: rs.TypeId | rs.Done = iter.next(); - if (_51 === rs.DONE) { + const _53: rs.TypeId | rs.Done = iter.next(); + if (_53 === rs.DONE) { break; } - const id: rs.TypeId = _51; + const id: rs.TypeId = _53; const part = rs.iterPosition(rs.iterSlice(ids), (i: rs.TypeId): boolean => { return i === id; }); put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part, f, rs.usizeDebug), " "])); } + const part2 = rs.iterPosition(rs.iterSlice(ids), (i2: rs.TypeId): boolean => { + return i2 === "cfb1622e7734f8af272d8d182905dc25"; + }); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part2, f, rs.usizeDebug), " "])); const iter2: rs.Iter = rs.iterSlice([new of$u8(a), new of$u32(n), new of$ids_Byte(byte), new of$ids_Mood(mood), new of$ref_str("str")]); while (true) { - const _87: Any.Any | rs.Done = iter2.next(); - if (_87 === rs.DONE) { + const _106: Any.Any | rs.Done = iter2.next(); + if (_106 === rs.DONE) { break; } - const part2 = rs.iterPosition(rs.iterSlice(ids), (i2: rs.TypeId): boolean => { - return i2 === _87.typeId$Any(); + const part3 = rs.iterPosition(rs.iterSlice(ids), (i3: rs.TypeId): boolean => { + return i3 === _106.typeId$Any(); }); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part2, f, rs.usizeDebug), " "])); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part3, f, rs.usizeDebug), " "])); } const iter3: rs.Iter = rs.iterSlice([new ofPlace$u32(rs.place(() => n, (value) => n = value)), new ofPlace$ids_Mood(rs.place(() => mood, (value2) => mood = value2))]); while (true) { - const _116: Any.Any | rs.Done = iter3.next(); - if (_116 === rs.DONE) { + const _135: Any.Any | rs.Done = iter3.next(); + if (_135 === rs.DONE) { break; } - const part3 = rs.iterPosition(rs.iterSlice(ids), (i3: rs.TypeId): boolean => { - return i3 === _116.typeId$Any(); + const part4 = rs.iterPosition(rs.iterSlice(ids), (i4: rs.TypeId): boolean => { + return i4 === _135.typeId$Any(); }); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part3, f, rs.usizeDebug), " "])); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part4, f, rs.usizeDebug), " "])); } const iter4: rs.Iter = rs.iterSlice([new of$u8(a), new of$ids_Byte(byte)]); while (true) { - const _146: Marked.Marked | rs.Done = iter4.next(); - if (_146 === rs.DONE) { + const _165: Marked.Marked | rs.Done = iter4.next(); + if (_165 === rs.DONE) { break; } - const any: Any.Any = _146; - const _159: rs.u8 = _146.tag$Marked(); - const _161: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i4: rs.TypeId): boolean => { - return i4 === _146.typeId$Any(); + const any: Any.Any = _165; + const _178: rs.u8 = _165.tag$Marked(); + const _180: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i5: rs.TypeId): boolean => { + return i5 === _165.typeId$Any(); }); - const _168: boolean = _146.typeId$Any() === any.typeId$Any(); - const _174: boolean = idOfVal$dyn_ids_Marked(_146) === "21b3f780835871567b1dbe5c04134c71"; - const args40 = [(f: rs.Formatter) => rs.u8Display(_159, f), (f: rs.Formatter) => rs.fmtOption(_161, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_168, f), (f: rs.Formatter) => rs.fmtBool(_174, f)]; - put(out, rs.fmtFormat([args40[0], " ", args40[1], " ", args40[2], " ", args40[3], " "])); + const _187: boolean = _165.typeId$Any() === any.typeId$Any(); + const _193: boolean = idOfVal$dyn_ids_Marked(_165) === "25e58479a985a0390f094b8a47a772ec"; + const args43 = [(f: rs.Formatter) => rs.u8Display(_178, f), (f: rs.Formatter) => rs.fmtOption(_180, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_187, f), (f: rs.Formatter) => rs.fmtBool(_193, f)]; + put(out, rs.fmtFormat([args43[0], " ", args43[1], " ", args43[2], " ", args43[3], " "])); } const boxes: rs.Vec = new rs.Vec(); for (const x of rs.byteSliceView(new rs.ByteSlice(dataData, dataStart + 2, dataLen - 2))) { - const _197: rs.u8 = rs.u8Rem(x, 3); - if (_197 === 0) { - _196 = new of$u8(x); - } else if (_197 === 1) { - _196 = new of$ids_Byte({ _0: x }); + const _216: rs.u8 = rs.u8Rem(x, 3); + if (_216 === 0) { + _215 = new of$u8(x); + } else if (_216 === 1) { + _215 = new of$ids_Byte({ _0: x }); } else { - _196 = new of$ids_Mood("Loud" as Mood.Mood); + _215 = new of$ids_Mood("Loud" as Mood.Mood); } - boxes.items.push(_196); + boxes.items.push(_215); } - for (const _207 of boxes.items) { - const inner: rs.TypeId = _207.typeId$Any(); - const _221: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i5: rs.TypeId): boolean => { - return i5 === inner; + for (const _226 of boxes.items) { + const inner: rs.TypeId = _226.typeId$Any(); + const _240: rs.usize | undefined = rs.iterPosition(rs.iterSlice(ids), (i6: rs.TypeId): boolean => { + return i6 === inner; }); - const _229: boolean = "37a732caafaf8e089d3a9d4c07b2ec78" === "37a732caafaf8e089d3a9d4c07b2ec78"; - const args41 = [(f: rs.Formatter) => rs.fmtOption(_221, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_229, f)]; - put(out, rs.fmtFormat([args41[0], " ", args41[1], " "])); + const _248: boolean = "37a732caafaf8e089d3a9d4c07b2ec78" === "37a732caafaf8e089d3a9d4c07b2ec78"; + const args44 = [(f: rs.Formatter) => rs.fmtOption(_240, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_248, f)]; + put(out, rs.fmtFormat([args44[0], " ", args44[1], " "])); } - const _240: rs.Arc = new rs.Arc(byte); - const shared: rs.Arc = new rs.ArcDyn(_240, new of$ids_Byte(_240.value)); + const _259: rs.Arc = new rs.Arc(byte); + const shared: rs.Arc = new rs.ArcDyn(_259, new of$ids_Byte(_259.value)); const boxed: Marked.Marked = new of$u8(a); - const _251: boolean = shared.value.typeId$Any() === "2dfe447c5824b47a6710c76af5f599c5"; - const _259: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; - const _266: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; - const args42 = [(f: rs.Formatter) => rs.fmtBool(_251, f), (f: rs.Formatter) => rs.fmtBool(_259, f), (f: rs.Formatter) => rs.fmtBool(_266, f)]; - put(out, rs.fmtFormat([args42[0], " ", args42[1], " ", args42[2], " "])); - const _279: rs.Slice = rs.sliceFrom(ids); + const _270: boolean = shared.value.typeId$Any() === "eb8e0be2af5c781063b1d1468b15a0f1"; + const _278: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; + const _285: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; + const args45 = [(f: rs.Formatter) => rs.fmtBool(_270, f), (f: rs.Formatter) => rs.fmtBool(_278, f), (f: rs.Formatter) => rs.fmtBool(_285, f)]; + put(out, rs.fmtFormat([args45[0], " ", args45[1], " ", args45[2], " "])); + const _298: rs.Slice = rs.sliceFrom(ids); const pairs: () => rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> = (): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { - return rs.iterFlatMap(rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_279))), (_210: [rs.usize, rs.TypeId]): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { - const i6: rs.usize = _210[0]; + return rs.iterFlatMap(rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_298))), (_210: [rs.usize, rs.TypeId]): rs.Iter<[rs.usize, rs.TypeId, rs.usize, rs.TypeId]> => { + const i7: rs.usize = _210[0]; const x3: rs.TypeId = _210[1]; - const _52: rs.Iter<[rs.usize, rs.TypeId]> = rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_279))); - const captured = i6; + const _52: rs.Iter<[rs.usize, rs.TypeId]> = rs.iterEnumerate(rs.iterSlice(rs.sliceItems(_298))); + const captured = i7; const captured2 = x3; return rs.iterMap(_52, (_211: [rs.usize, rs.TypeId]): [rs.usize, rs.TypeId, rs.usize, rs.TypeId] => { return [captured, captured2, _211[0], _211[1]] as [rs.usize, rs.TypeId, rs.usize, rs.TypeId]; }); }, undefined, true); }; - const _288: boolean = rs.iterAll(pairs(), (_212: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { - const i7: rs.usize = _212[0]; + const _307: boolean = rs.iterAll(pairs(), (_212: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const i8: rs.usize = _212[0]; const x4: rs.TypeId = _212[1]; const j2: rs.usize = _212[2]; const y3: rs.TypeId = _212[3]; - if (!(x4 === y3 === (i7 === j2))) { + if (!(x4 === y3 === (i8 === j2))) { return false; } - return x4 !== y3 === (i7 !== j2); + return x4 !== y3 === (i8 !== j2); }); - const _293: boolean = rs.iterAll(pairs(), (_213: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const _312: boolean = rs.iterAll(pairs(), (_213: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { const x5: rs.TypeId = _213[1]; const y4: rs.TypeId = _213[3]; - const _610: rs.Ordering = rs.typeIdCmp(x5, y4); - const _127: rs.Vec = words(x5); - const _143: rs.Vec = words(y4); - return _610 === rs.cmpSlice(rs.cmp)(_127, _143); + const _613: rs.Ordering = rs.typeIdCmp(x5, y4); + const _1211: rs.Vec = words(x5); + const _145: rs.Vec = words(y4); + return _613 === rs.cmpSlice(rs.cmp)(_1211, _145); }); - const _298: boolean = rs.iterAll(pairs(), (_215: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { - const x6: rs.TypeId = _215[1]; - const y5: rs.TypeId = _215[3]; - const _619: rs.Ordering | undefined = rs.typeIdCmp(x6, y5); - const _134: rs.Vec = words(x6); - const _157: rs.Vec = words(y5); - return _619 === rs.cmpSlice(rs.cmp)(_134, _157) as rs.Ordering | undefined; + const _317: boolean = rs.iterAll(pairs(), (_224: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const x6: rs.TypeId = _224[1]; + const y5: rs.TypeId = _224[3]; + const _614: rs.Ordering | undefined = rs.typeIdCmp(x6, y5); + const _136: rs.Vec = words(x6); + const _154: rs.Vec = words(y5); + return _614 === rs.cmpSlice(rs.cmp)(_136, _154) as rs.Ordering | undefined; }); - const _303: boolean = rs.iterAll(pairs(), (_219: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { - const x7: rs.TypeId = _219[1]; - const y6: rs.TypeId = _219[3]; - const _620: boolean = rs.typeIdCmp(x7, y6) === -1; + const _322: boolean = rs.iterAll(pairs(), (_225: [rs.usize, rs.TypeId, rs.usize, rs.TypeId]): boolean => { + const x7: rs.TypeId = _225[1]; + const y6: rs.TypeId = _225[3]; + const _616: boolean = rs.typeIdCmp(x7, y6) === -1; const _1112: rs.Vec = words(x7); - const _139: rs.Vec = words(y6); - if (!(_620 === (rs.cmpSlice(rs.cmp)(_1112, _139) === -1))) { + const _138: rs.Vec = words(y6); + if (!(_616 === (rs.cmpSlice(rs.cmp)(_1112, _138) === -1))) { return false; } const order2 = rs.typeIdCmp(x7, y6); - const _145: boolean = order2 !== undefined && order2 >= 0; + const _146: boolean = order2 !== undefined && order2 >= 0; const _192: rs.Vec = words(x7); const _2110: rs.Vec = words(y6); const order3 = rs.cmpSlice(rs.cmp)(_192, _2110); - return _145 === (order3 !== undefined && order3 >= 0); + return _146 === (order3 !== undefined && order3 >= 0); }); - const args43 = [(f: rs.Formatter) => rs.fmtBool(_288, f), (f: rs.Formatter) => rs.fmtBool(_293, f), (f: rs.Formatter) => rs.fmtBool(_298, f), (f: rs.Formatter) => rs.fmtBool(_303, f)]; - put(out, rs.fmtFormat([args43[0], " ", args43[1], " ", args43[2], " ", args43[3], " "])); - const _318: rs.usize = rs.usizeRem(a as rs.usize, rs.sliceFrom(ids).length); - if (!(_318 < 13)) { - rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _318); + const args46 = [(f: rs.Formatter) => rs.fmtBool(_307, f), (f: rs.Formatter) => rs.fmtBool(_312, f), (f: rs.Formatter) => rs.fmtBool(_317, f), (f: rs.Formatter) => rs.fmtBool(_322, f)]; + put(out, rs.fmtFormat([args46[0], " ", args46[1], " ", args46[2], " ", args46[3], " "])); + const _337: rs.usize = rs.usizeRem(a as rs.usize, rs.sliceFrom(ids).length); + if (!(_337 < 13)) { + rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _337); } - const _317: rs.TypeId = ids[_318]; - const _326: rs.usize = rs.usizeRem(b as rs.usize, rs.sliceFrom(ids).length); - if (!(_326 < 13)) { - rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _326); + const _336: rs.TypeId = ids[_337]; + const _345: rs.usize = rs.usizeRem(b as rs.usize, rs.sliceFrom(ids).length); + if (!(_345 < 13)) { + rs.panic("index out of bounds: the len is " + 13 + " but the index is " + _345); } - const _316: [rs.TypeId, rs.TypeId] = [_317, ids[_326]]; - const x2: rs.TypeId = _317; - const y: rs.TypeId = _316[1]; - const part4 = rs.iterAll(rs.iterSlice(ids), (_220: rs.TypeId): boolean => { - return hashOf(_220) !== undefined; + const _335: [rs.TypeId, rs.TypeId] = [_336, ids[_345]]; + const x2: rs.TypeId = _336; + const y: rs.TypeId = _335[1]; + const part5 = rs.iterAll(rs.iterSlice(ids), (_227: rs.TypeId): boolean => { + return hashOf(_227) !== undefined; }); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(part4, f), " "])); - const _352: [rs.Result, Capped.Capped] = capped(x2, rs.u8Rem(a, 10) as rs.usize); - const result: rs.Result = _352[0]; - const w: Capped.Capped = _352[1]; - const _367: rs.Fmt = (f: rs.Formatter) => rs.fmtResult(result, f, rs.fmtUnit, rs.fmtErrorDebug); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(part5, f), " "])); + const _371: [rs.Result, Capped.Capped] = capped(x2, rs.u8Rem(a, 10) as rs.usize); + const result: rs.Result = _371[0]; + const w: Capped.Capped = _371[1]; + const _386: rs.Fmt = (f: rs.Formatter) => rs.fmtResult(result, f, rs.fmtUnit, rs.fmtErrorDebug); const arg = w.calls; - const _368: rs.Fmt = (f: rs.Formatter) => rs.usizeDisplay(arg, f); + const _387: rs.Fmt = (f: rs.Formatter) => rs.usizeDisplay(arg, f); const arg2 = w.log; - const args45 = [_367, _368, (f: rs.Formatter) => rs.fmtList(arg2.items, f, rs.fmtStr)]; - put(out, rs.fmtFormat([args45[0], " ", args45[1], " ", args45[2], " "])); + const args48 = [_386, _387, (f: rs.Formatter) => rs.fmtList(arg2.items, f, rs.fmtStr)]; + put(out, rs.fmtFormat([args48[0], " ", args48[1], " ", args48[2], " "])); const debug: string = rs.fmtFormat([(f: rs.Formatter) => rs.fmtTypeIdDebug(x2, f)]); - const zeros: rs.usize = rs.min(rs.iterCount(rs.iterTakeWhile(rs.strBytes(rs.strSlice(debug, 9)), (_222: rs.u8): boolean => { - return _222 === 48; + const zeros: rs.usize = rs.min(rs.iterCount(rs.iterTakeWhile(rs.strBytes(rs.strSlice(debug, 9)), (_228: rs.u8): boolean => { + return _228 === 48; })), 31); - const _390: [rs.Result, Capped.Capped] = capped(x2, 4294967295); - const result2: rs.Result = _390[0]; - const w2: Capped.Capped = _390[1]; - const part5 = rs.usizeSub(w2.log.items.length, 1); - const _394: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 2, part5); + const _409: [rs.Result, Capped.Capped] = capped(x2, 4294967295); + const result2: rs.Result = _409[0]; + const w2: Capped.Capped = _409[1]; + const part6 = rs.usizeSub(w2.log.items.length, 1); + const _413: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 2, part6); const n2: rs.usize = w2.log.items.length; - const _412: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 0, 2); - const _416: string | undefined = rs.sliceLast(rs.sliceFrom(w2.log.items)); + const _431: rs.Slice = rs.sliceRange(rs.sliceFrom(w2.log.items), 0, 2); + const _435: string | undefined = rs.sliceLast(rs.sliceFrom(w2.log.items)); if (!(n2 === rs.usizeAdd(4, zeros))) { - _420 = false; + _439 = false; } else { - _420 = rs.iterAll(rs.iterSlice(rs.sliceItems(rs.sliceRange(_394, 0, zeros))), (d: string): boolean => { + _439 = rs.iterAll(rs.iterSlice(rs.sliceItems(rs.sliceRange(_413, 0, zeros))), (d: string): boolean => { return d === "0"; }); } - const _419: boolean = _420; - const _429: boolean = rs.strsJoin(rs.sliceItems(_394), "") === rs.strSlice(debug, 9, 41); - const args47 = [(f: rs.Formatter) => rs.fmtResult(result2, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtList(rs.sliceItems(_412), f, rs.fmtStr), (f: rs.Formatter) => rs.fmtOption(_416, f, rs.fmtStr), (f: rs.Formatter) => rs.fmtBool(_419, f), (f: rs.Formatter) => rs.fmtBool(_429, f)]; - put(out, rs.fmtFormat([args47[0], " ", args47[1], " ", args47[2], " ", args47[3], " ", args47[4], " "])); - const _447: rs.usize = rs.usizeSub(rs.stringLen(debug), 1); - const _446: [rs.Result, Capped.Capped] = capped(x2, _447); - const result3: rs.Result = _446[0]; - const _459: boolean = rs.strsJoin(_446[1].log.items, "") + ")" === debug; - const args48 = [(f: rs.Formatter) => rs.fmtResult(result3, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtBool(_459, f)]; - put(out, rs.fmtFormat([args48[0], " ", args48[1], " "])); + const _438: boolean = _439; + const _448: boolean = rs.strsJoin(rs.sliceItems(_413), "") === rs.strSlice(debug, 9, 41); + const args50 = [(f: rs.Formatter) => rs.fmtResult(result2, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtList(rs.sliceItems(_431), f, rs.fmtStr), (f: rs.Formatter) => rs.fmtOption(_435, f, rs.fmtStr), (f: rs.Formatter) => rs.fmtBool(_438, f), (f: rs.Formatter) => rs.fmtBool(_448, f)]; + put(out, rs.fmtFormat([args50[0], " ", args50[1], " ", args50[2], " ", args50[3], " ", args50[4], " "])); + const _466: rs.usize = rs.usizeSub(rs.stringLen(debug), 1); + const _465: [rs.Result, Capped.Capped] = capped(x2, _466); + const result3: rs.Result = _465[0]; + const _478: boolean = rs.strsJoin(_465[1].log.items, "") + ")" === debug; + const args51 = [(f: rs.Formatter) => rs.fmtResult(result3, f, rs.fmtUnit, rs.fmtErrorDebug), (f: rs.Formatter) => rs.fmtBool(_478, f)]; + put(out, rs.fmtFormat([args51[0], " ", args51[1], " "])); const log: Log.Log = Log.default$Default(); rs.typeIdHash(x2, new rs.OwnHasher(log, Log.hasher$hash_Hasher)); const high: string | undefined = option_map$1tqulv0(hashOf(x2), (h: rs.u128): string => { - const part6 = rs.u128Shr(h, 64); - return rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u128LowerHex(part6, f)]); + const part7 = rs.u128Shr(h, 64); + return rs.fmtFormat(["u64 ", (f: rs.Formatter) => rs.u128LowerHex(part7, f)]); }); - const _487: rs.usize = log._0.items.length; - const _490: boolean = rs.sliceFirst(rs.sliceFrom(log._0.items)) === high; - const args52 = [(f: rs.Formatter) => rs.usizeDisplay(_487, f), (f: rs.Formatter) => rs.fmtBool(_490, f)]; - put(out, rs.fmtFormat([args52[0], " ", args52[1], " "])); - const _513: rs.TypeId = rs.ordMax(x2, y, rs.cmpLt(rs.typeIdCmp)); - const _518: rs.Vec = words(x2); - const _520: rs.Vec = words(y); - if (!(rs.cmpSlice(rs.cmp)(_518, _520) === -1)) { - _515 = x2; + const _506: rs.usize = log._0.items.length; + const _509: boolean = rs.sliceFirst(rs.sliceFrom(log._0.items)) === high; + const args55 = [(f: rs.Formatter) => rs.usizeDisplay(_506, f), (f: rs.Formatter) => rs.fmtBool(_509, f)]; + put(out, rs.fmtFormat([args55[0], " ", args55[1], " "])); + const _532: rs.TypeId = rs.ordMax(x2, y, rs.cmpLt(rs.typeIdCmp)); + const _537: rs.Vec = words(x2); + const _539: rs.Vec = words(y); + if (!(rs.cmpSlice(rs.cmp)(_537, _539) === -1)) { + _534 = x2; } else { - _515 = y; + _534 = y; } - const arg3 = _513 === _515; + const arg3 = _532 === _534; put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtBool(arg3, f), " "])); const sorted: rs.Vec = rs.vecFrom(ids.slice()); rs.sliceSort(rs.sliceFrom(sorted.items), rs.cmpLt(rs.typeIdCmp), 16, true); const ordered: boolean = rs.iterAll(rs.sliceWindows(rs.sliceFrom(sorted.items), 2), (w4: rs.Slice): boolean => { rs.idx(w4, 0); - const _424: rs.Vec = words(w4.data[w4.start]); + const _422: rs.Vec = words(w4.data[w4.start]); rs.idx(w4, 1); - const _1011: rs.Vec = words(w4.data[w4.start + 1]); - return rs.cmpSlice(rs.cmp)(_424, _1011) === -1; + const _109: rs.Vec = words(w4.data[w4.start + 1]); + return rs.cmpSlice(rs.cmp)(_422, _109) === -1; }); - const _537: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); - const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.typeIdCmp) as rs.BTreeSet, _537, true, undefined, undefined, 16, true); - const _544: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); - const hashed: rs.HashSet = rs.hashExtendKeys(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashSet, _544, undefined, undefined, 58720256); - const _558: rs.usize = rs.btreeLen(set); - const _561: rs.usize = rs.hashLen(hashed); - const args54 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_558, f), (f: rs.Formatter) => rs.usizeDisplay(_561, f)]; - put(out, rs.fmtFormat([args54[0], " ", args54[1], " ", args54[2], " "])); - const _571: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["2dfe447c5824b47a6710c76af5f599c5", "byte"] as [rs.TypeId, string], ["ff641c451ae80e5aeea189eeac47965a", "mood"] as [rs.TypeId, string]]); - const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _571, undefined, undefined, undefined, 58720256); - for (const _584 of boxes.items) { - const part7 = rs.hashGet(names, _584.typeId$Any()); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part7, f, rs.fmtStr), " "])); + const _556: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.typeIdCmp) as rs.BTreeSet, _556, true, undefined, undefined, 16, true); + const _563: rs.Iter = rs.iterChain(rs.iterSlice(ids), rs.iterSlice(found)); + const hashed: rs.HashSet = rs.hashExtendKeys(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashSet, _563, undefined, undefined, 58720256); + const _577: rs.usize = rs.btreeLen(set); + const _580: rs.usize = rs.hashLen(hashed); + const args57 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_577, f), (f: rs.Formatter) => rs.usizeDisplay(_580, f)]; + put(out, rs.fmtFormat([args57[0], " ", args57[1], " ", args57[2], " "])); + const _590: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["eb8e0be2af5c781063b1d1468b15a0f1", "byte"] as [rs.TypeId, string], ["180954c559d9dbe8afcd63c1da176c31", "mood"] as [rs.TypeId, string]]); + const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _590, undefined, undefined, undefined, 58720256); + for (const _603 of boxes.items) { + const part8 = rs.hashGet(names, _603.typeId$Any()); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtOption(part8, f, rs.fmtStr), " "])); } const keys: WithId.WithId[] = [{ id: x2, n: a }, { id: y, n: b }, { id: x2, n: b }]; - const _617: rs.Slice = rs.sliceFrom(keys); - const part10 = rs.iterToVec(rs.iterMap(rs.iterFlatMap(rs.iterSlice(keys), (k2: WithId.WithId): rs.Iter<[WithId.WithId, WithId.WithId]> => { - return rs.iterMap(rs.iterSlice(rs.sliceItems(_617)), (l2: WithId.WithId): [WithId.WithId, WithId.WithId] => { + const _636: rs.Slice = rs.sliceFrom(keys); + const part11 = rs.iterToVec(rs.iterMap(rs.iterFlatMap(rs.iterSlice(keys), (k2: WithId.WithId): rs.Iter<[WithId.WithId, WithId.WithId]> => { + return rs.iterMap(rs.iterSlice(rs.sliceItems(_636)), (l2: WithId.WithId): [WithId.WithId, WithId.WithId] => { return [k2, l2] as [WithId.WithId, WithId.WithId]; }); - }, undefined, true), (_227: [WithId.WithId, WithId.WithId]): [boolean, boolean] => { - const k3: WithId.WithId = _227[0]; - const l3: WithId.WithId = _227[1]; - return [WithId.eq$cmp_PartialEq(k3, l3), WithId.cmp$cmp_Ord(k3, l3) === _609(k3, l3)] as [boolean, boolean]; + }, undefined, true), (_229: [WithId.WithId, WithId.WithId]): [boolean, boolean] => { + const k3: WithId.WithId = _229[0]; + const l3: WithId.WithId = _229[1]; + return [WithId.eq$cmp_PartialEq(k3, l3), WithId.cmp$cmp_Ord(k3, l3) === _628(k3, l3)] as [boolean, boolean]; }), "next", 2); - put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(part10.items, f, (value: [boolean, boolean], f: rs.Formatter) => rs.fmtTuple([(f: rs.Formatter) => rs.fmtBool(value[0], f), (f: rs.Formatter) => rs.fmtBool(value[1], f)], f)), " "])); + put(out, rs.fmtFormat([(f: rs.Formatter) => rs.fmtList(part11.items, f, (value: [boolean, boolean], f: rs.Formatter) => rs.fmtTuple([(f: rs.Formatter) => rs.fmtBool(value[0], f), (f: rs.Formatter) => rs.fmtBool(value[1], f)], f)), " "])); const log2: Log.Log = Log.default$Default(); WithId.hash$Hash_ids_Log(keys[0], log2); - const _646: rs.usize = log2._0.items.length; - const _649: string | undefined = rs.sliceGet(rs.sliceFrom(log2._0.items), 1); - const args57 = [(f: rs.Formatter) => rs.usizeDisplay(_646, f), (f: rs.Formatter) => rs.fmtOption(_649, f, rs.fmtStr)]; - put(out, rs.fmtFormat([args57[0], " ", args57[1]])); + const _665: rs.usize = log2._0.items.length; + const _668: string | undefined = rs.sliceGet(rs.sliceFrom(log2._0.items), 1); + const args60 = [(f: rs.Formatter) => rs.usizeDisplay(_665, f), (f: rs.Formatter) => rs.fmtOption(_668, f, rs.fmtStr)]; + put(out, rs.fmtFormat([args60[0], " ", args60[1]])); rs.drop(boxed); shared[Symbol.dispose](); rs.dropVec(boxes); diff --git a/ts/fixtures/lang/dyns/src/ids.rs b/ts/fixtures/lang/dyns/src/ids.rs index 7665eaf39..18ca24550 100644 --- a/ts/fixtures/lang/dyns/src/ids.rs +++ b/ts/fixtures/lang/dyns/src/ids.rs @@ -104,6 +104,9 @@ fn capped(id: TypeId, cap: usize) -> (fmt::Result, Capped) { /// A `TypeId` the compiler evaluates. const U8: TypeId = TypeId::of::(); +/// A reference to one, which the compiler places in memory. +const U8_REF: &TypeId = &TypeId::of::(); + /// `T`'s `TypeId`, through a type parameter. fn id_of() -> TypeId { TypeId::of::() @@ -161,6 +164,7 @@ pub fn ids(data: &[u8], out: &mut Vec) { let found = [ id_of::(), U8, + *U8_REF, const { TypeId::of::() }, a.type_id(), n.type_id(), @@ -173,6 +177,7 @@ pub fn ids(data: &[u8], out: &mut Vec) { for id in found { put(out, &format!("{:?} ", ids.iter().position(|i| *i == id))); } + put(out, &format!("{:?} ", ids.iter().position(|i| i == U8_REF))); // A trait object's is its value's, borrowed, changed in place, which JS copies for a // number and an enum, boxed, shared, and upcast, but a box's and an `Rc`'s own are theirs. diff --git a/ts/fixtures/lang/panics/hook/expected/core/any.Any.ts b/ts/fixtures/lang/panics/hook/expected/core/any.Any.ts index ba72bb625..fd88dfe56 100644 --- a/ts/fixtures/lang/panics/hook/expected/core/any.Any.ts +++ b/ts/fixtures/lang/panics/hook/expected/core/any.Any.ts @@ -1,5 +1,7 @@ // Generated by rust2-ts. Do not edit. -export type Any = object; +import * as rs from "../rs.ts"; + +export type Any = { typeId$Any: () => rs.TypeId }; //# sourceMappingURL=any.Any.ts.map diff --git a/ts/fixtures/lang/panics/hook/expected/hooked.ts b/ts/fixtures/lang/panics/hook/expected/hooked.ts index f377e9b09..424a62564 100644 --- a/ts/fixtures/lang/panics/hook/expected/hooked.ts +++ b/ts/fixtures/lang/panics/hook/expected/hooked.ts @@ -1,7 +1,7 @@ // Generated by rust2-ts. Do not edit. import * as rs from "./rs.ts"; -import { drop$Result_sync_MutexGuard_u8_sync_PoisonError_sync_MutexGuard_u8, drop$bytes_buf_Take_bytes_Bytes, of$String, of$ref_str, of$u32, of$u8, ofPlace$String, ofPlace$ref_str, ofPlace$u32, ofPlace$u8, NOTE } from "./lib.ts"; +import { drop$Result_sync_MutexGuard_u8_sync_PoisonError_sync_MutexGuard_u8, drop$bytes_buf_Take_bytes_Bytes, of$String, of$ref_str, of$u32, of$u8, ofPlace$String, ofPlace$u32, ofPlace$u8, NOTE } from "./lib.ts"; import { take$bytes_Buf_bytes_Bytes as buf_impl_take$bytes_Buf_bytes_Bytes } from "./bytes/buf/buf_impl.ts"; import * as Take from "./bytes/buf/take.Take.ts"; import * as UninitSlice from "./bytes/buf/uninit_slice.UninitSlice.ts"; @@ -20,15 +20,15 @@ import { withBorrow$097wfl1 } from "./std/thread/local.ts"; export function record(info: rs.PanicHookInfo): void { let kind!: string; const payload: Any.Any = rs.hookPayload(info, of$ref_str, of$String); - if (!(payload instanceof of$ref_str || payload instanceof ofPlace$ref_str)) { + if (!(payload.typeId$Any() === "24c161f26c70c1f1b9f602dc5fe9f65c")) { if (!(payload instanceof of$String || payload instanceof ofPlace$String)) { - const _8: rs.u32 | undefined = payload instanceof of$u32 ? payload.v : payload instanceof ofPlace$u32 ? payload.v.v : undefined; - if (_8 !== undefined) { - kind = rs.fmtFormat(["u32 ", (f: rs.Formatter) => rs.u32Display(_8, f)]); + const _12: rs.u32 | undefined = payload instanceof of$u32 ? payload.v : payload instanceof ofPlace$u32 ? payload.v.v : undefined; + if (_12 !== undefined) { + kind = rs.fmtFormat(["u32 ", (f: rs.Formatter) => rs.u32Display(_12, f)]); } else { - const _19: rs.u8 | undefined = payload instanceof of$u8 ? payload.v : payload instanceof ofPlace$u8 ? payload.v.v : undefined; - if (_19 !== undefined) { - kind = rs.fmtFormat(["u8 ", (f: rs.Formatter) => rs.u8Display(_19, f)]); + const _23: rs.u8 | undefined = payload instanceof of$u8 ? payload.v : payload instanceof ofPlace$u8 ? payload.v.v : undefined; + if (_23 !== undefined) { + kind = rs.fmtFormat(["u8 ", (f: rs.Formatter) => rs.u8Display(_23, f)]); } else { kind = "other"; } @@ -40,13 +40,13 @@ export function record(info: rs.PanicHookInfo): void { kind = "&str"; } const at: rs.Location = rs.optionUnwrap(info.location, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 42, col: 30 }); - const _38: string = rs.strReplace(rs.fmtToString((f: rs.Formatter) => rs.fmtPanicHookInfoDisplay(info, f)), at.file, stdNamed(at.file)); - const _48: string | undefined = info.text; - const _50: string = stdNamed(at.file); - const _53: rs.u32 = at.line; - const _55: rs.u32 = at.col; - const _57: boolean = rs.panicking(); - const args9 = [(f: rs.Formatter) => rs.fmtPad(f, _38), (f: rs.Formatter) => rs.fmtPad(f, kind), (f: rs.Formatter) => rs.fmtOption(_48, f, rs.fmtStr), (f: rs.Formatter) => rs.fmtPad(f, _50), (f: rs.Formatter) => rs.u32Display(_53, f), (f: rs.Formatter) => rs.u32Display(_55, f), (f: rs.Formatter) => rs.fmtBool(_57, f)]; + const _42: string = rs.strReplace(rs.fmtToString((f: rs.Formatter) => rs.fmtPanicHookInfoDisplay(info, f)), at.file, stdNamed(at.file)); + const _52: string | undefined = info.text; + const _54: string = stdNamed(at.file); + const _57: rs.u32 = at.line; + const _59: rs.u32 = at.col; + const _61: boolean = rs.panicking(); + const args9 = [(f: rs.Formatter) => rs.fmtPad(f, _42), (f: rs.Formatter) => rs.fmtPad(f, kind), (f: rs.Formatter) => rs.fmtOption(_52, f, rs.fmtStr), (f: rs.Formatter) => rs.fmtPad(f, _54), (f: rs.Formatter) => rs.u32Display(_57, f), (f: rs.Formatter) => rs.u32Display(_59, f), (f: rs.Formatter) => rs.fmtBool(_61, f)]; const line: string = rs.fmtFormat([args9[0], "\n", args9[1], " ", args9[2], " ", args9[3], " ", args9[4], " ", args9[5], " ", args9[6], "\n"]); rs.localKeyWithBorrowMutPlace(NOTE, (note: rs.Place): undefined => { note.v = note.v + line; diff --git a/ts/fixtures/lang/panics/hook/expected/lib.ts b/ts/fixtures/lang/panics/hook/expected/lib.ts index bcbdec6d5..20bf56818 100644 --- a/ts/fixtures/lang/panics/hook/expected/lib.ts +++ b/ts/fixtures/lang/panics/hook/expected/lib.ts @@ -39,6 +39,10 @@ export class of$String { constructor(v: string) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "1430db79e63c4bb92bf94c26df7c977d"; + } } export class of$located_Inherits { @@ -75,6 +79,10 @@ export class of$panics_Point { constructor(v: Point.Point) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "37e450afe4d41be326161cb6b122df94"; + } } export class of$ref_str { @@ -83,6 +91,10 @@ export class of$ref_str { constructor(v: string) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "24c161f26c70c1f1b9f602dc5fe9f65c"; + } } export class of$u32 { @@ -91,6 +103,10 @@ export class of$u32 { constructor(v: rs.u32) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "79f19461b401588885a89e43144b08f1"; + } } export class of$u8 { @@ -104,6 +120,10 @@ export class of$u8 { return at$located_Tracked_u8(this.v, caller); } + typeId$Any(): rs.TypeId { + return "cfb1622e7734f8af272d8d182905dc25"; + } + via$Tracked(): rs.Location { return via$located_Tracked_u8(this.v); } @@ -115,13 +135,9 @@ export class ofPlace$String { constructor(v: rs.Place) { this.v = v; } -} - -export class ofPlace$ref_str { - v: rs.Place; - constructor(v: rs.Place) { - this.v = v; + typeId$Any(): rs.TypeId { + return "1430db79e63c4bb92bf94c26df7c977d"; } } @@ -131,6 +147,10 @@ export class ofPlace$u32 { constructor(v: rs.Place) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "79f19461b401588885a89e43144b08f1"; + } } export class ofPlace$u8 { @@ -139,6 +159,10 @@ export class ofPlace$u8 { constructor(v: rs.Place) { this.v = v; } + + typeId$Any(): rs.TypeId { + return "cfb1622e7734f8af272d8d182905dc25"; + } } /** diff --git a/ts/fixtures/lang/panics/src/hooked.rs b/ts/fixtures/lang/panics/src/hooked.rs index d83d037e7..66e07c0bd 100644 --- a/ts/fixtures/lang/panics/src/hooked.rs +++ b/ts/fixtures/lang/panics/src/hooked.rs @@ -28,7 +28,7 @@ use crate::NOTE; /// parts, and whether the thread is panicking. fn record(info: &PanicHookInfo<'_>) { let payload = info.payload(); - let kind = if payload.is::<&'static str>() { + let kind = if payload.type_id() == std::any::TypeId::of::<&'static str>() { "&str".to_string() } else if payload.is::() { "String".to_string() diff --git a/ts/runtime/rs/hook.ts b/ts/runtime/rs/hook.ts index 5473a709b..ed07318b9 100644 --- a/ts/runtime/rs/hook.ts +++ b/ts/runtime/rs/hook.ts @@ -97,8 +97,9 @@ export function panicAny(payload: object, at?: Location): never { * `PanicHookInfo::payload`: what `panic_any` was given, or else the text, as a `str` or a * `String` object, whose classes translation makes. */ -export function hookPayload(info: PanicHookInfo, str: new (text: string) => object, string: new (text: string) => object): object { - return info.payload ?? new (info.owned ? string : str)(info.text ?? ""); +export function hookPayload(info: PanicHookInfo, str: new (text: string) => T, string: new (text: string) => T): T { + // `panic_any` made its payload an object of the same `dyn Any` the classes are. + return (info.payload as T | undefined) ?? new (info.owned ? string : str)(info.text ?? ""); } /** `PanicHookInfo`'s `Display`: where it panicked, then any text, as the default hook's first lines. */ diff --git a/ts/src/lower/mir/place.rs b/ts/src/lower/mir/place.rs index 5abe05758..26d77f864 100644 --- a/ts/src/lower/mir/place.rs +++ b/ts/src/lower/mir/place.rs @@ -1666,6 +1666,14 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { ); }; let unnamed = format!("a constant of type `{ty}`, a pointer into memory translation can't name"); + // A `&TypeId`, or a reference to one, which translation holds as the `TypeId`. + if self.b.t.std_of(ty.peel_refs()) == Some(Std::TypeId) { + let val = ConstValue::Indirect { + alloc_id: prov.alloc_id(), + offset, + }; + return self.const_value(val, *inner, span); + } // A `Location`, as `Location::caller` gives a constant. if self.b.t.std_of(*inner) == Some(Std::Location) { return match self.location_const(alloc, offset, *inner) { From a41df849c1a12bd5fcabf44c313e565b4e031851 Mon Sep 17 00:00:00 2001 From: quest fixer Date: Fri, 6 Nov 2026 21:33:45 -0800 Subject: [PATCH 09/10] chore(ts): regenerate TypeId fixture snapshots after base merge --- ts/fixtures/lang/dyns/expected/ids.ts | 14 +++++++------- ts/fixtures/lang/dyns/expected/lib.ts | 14 +++++++------- ts/fixtures/lang/panics/hook/expected/lib.ts | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ts/fixtures/lang/dyns/expected/ids.ts b/ts/fixtures/lang/dyns/expected/ids.ts index ccf239675..e04893018 100644 --- a/ts/fixtures/lang/dyns/expected/ids.ts +++ b/ts/fixtures/lang/dyns/expected/ids.ts @@ -42,12 +42,12 @@ export function idOfVal$dyn_Any(_1: Any.Any): rs.TypeId { /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$dyn_ids_Marked(_1: Marked.Marked): rs.TypeId { - return "25e58479a985a0390f094b8a47a772ec"; + return "3bbda84d3ea87978c3191a064aa30838"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$ids_Mood(_1: Mood.Mood): rs.TypeId { - return "180954c559d9dbe8afcd63c1da176c31"; + return "586c02dbd458954a051f9cd00d861391"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ @@ -116,8 +116,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou mood = "Calm" as Mood.Mood; } const byte: Byte.Byte = { _0: b }; - const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "eb8e0be2af5c781063b1d1468b15a0f1", "180954c559d9dbe8afcd63c1da176c31", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "25e58479a985a0390f094b8a47a772ec", "25ff997ce0b3a76fb5ce30b55accc57f"]; - const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "cfb1622e7734f8af272d8d182905dc25", "eb8e0be2af5c781063b1d1468b15a0f1", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "eb8e0be2af5c781063b1d1468b15a0f1", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; + const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "47cf44edf6d848167c2724f9fe31a15d", "586c02dbd458954a051f9cd00d861391", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "3bbda84d3ea87978c3191a064aa30838", "25ff997ce0b3a76fb5ce30b55accc57f"]; + const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "cfb1622e7734f8af272d8d182905dc25", "47cf44edf6d848167c2724f9fe31a15d", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "47cf44edf6d848167c2724f9fe31a15d", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; const iter: rs.Iter = rs.iterSlice(found); while (true) { const _53: rs.TypeId | rs.Done = iter.next(); @@ -168,7 +168,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou return i5 === _165.typeId$Any(); }); const _187: boolean = _165.typeId$Any() === any.typeId$Any(); - const _193: boolean = idOfVal$dyn_ids_Marked(_165) === "25e58479a985a0390f094b8a47a772ec"; + const _193: boolean = idOfVal$dyn_ids_Marked(_165) === "3bbda84d3ea87978c3191a064aa30838"; const args43 = [(f: rs.Formatter) => rs.u8Display(_178, f), (f: rs.Formatter) => rs.fmtOption(_180, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_187, f), (f: rs.Formatter) => rs.fmtBool(_193, f)]; put(out, rs.fmtFormat([args43[0], " ", args43[1], " ", args43[2], " ", args43[3], " "]).v); } @@ -196,7 +196,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _259: rs.Arc = new rs.Arc(byte); const shared: rs.Arc = new rs.ArcDyn(_259, new of$ids_Byte(_259.value)); const boxed: Marked.Marked = new of$u8(a); - const _270: boolean = shared.value.typeId$Any() === "eb8e0be2af5c781063b1d1468b15a0f1"; + const _270: boolean = shared.value.typeId$Any() === "47cf44edf6d848167c2724f9fe31a15d"; const _278: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; const _285: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; const args45 = [(f: rs.Formatter) => rs.fmtBool(_270, f), (f: rs.Formatter) => rs.fmtBool(_278, f), (f: rs.Formatter) => rs.fmtBool(_285, f)]; @@ -349,7 +349,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _580: rs.usize = rs.hashLen(hashed); const args57 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_577, f), (f: rs.Formatter) => rs.usizeDisplay(_580, f)]; put(out, rs.fmtFormat([args57[0], " ", args57[1], " ", args57[2], " "]).v); - const _590: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["eb8e0be2af5c781063b1d1468b15a0f1", "byte"] as [rs.TypeId, string], ["180954c559d9dbe8afcd63c1da176c31", "mood"] as [rs.TypeId, string]]); + const _590: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["47cf44edf6d848167c2724f9fe31a15d", "byte"] as [rs.TypeId, string], ["586c02dbd458954a051f9cd00d861391", "mood"] as [rs.TypeId, string]]); const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _590, undefined, undefined, undefined, 58720256); for (const _603 of boxes.items) { const part8 = rs.hashGet(names, _603.typeId$Any()); diff --git a/ts/fixtures/lang/dyns/expected/lib.ts b/ts/fixtures/lang/dyns/expected/lib.ts index 35b5212b6..727b91997 100644 --- a/ts/fixtures/lang/dyns/expected/lib.ts +++ b/ts/fixtures/lang/dyns/expected/lib.ts @@ -583,7 +583,7 @@ export class of$dyns_Noisy { } typeId$Any(): rs.TypeId { - return "629ea3d0db74a6a4121c4b5c2ea86c5d"; + return "16a5b7dad13abb2368cccd1d4411ed29"; } } @@ -659,7 +659,7 @@ export class of$dyns_Square { } typeId$Any(): rs.TypeId { - return "4d27e589f80a9b722ffd015b418dab46"; + return "2bc6a9a6ddabf1ab5bf7f2ef98b9915f"; } } @@ -751,7 +751,7 @@ export class of$dyns_Tri { } typeId$Any(): rs.TypeId { - return "db6a2678079cd6de1063f521a32772c0"; + return "1efc30ab591c39470b121f4a2de91e05"; } } @@ -859,7 +859,7 @@ export class of$ids_Byte { } typeId$Any(): rs.TypeId { - return "eb8e0be2af5c781063b1d1468b15a0f1"; + return "47cf44edf6d848167c2724f9fe31a15d"; } } @@ -871,7 +871,7 @@ export class of$ids_Mood { } typeId$Any(): rs.TypeId { - return "180954c559d9dbe8afcd63c1da176c31"; + return "586c02dbd458954a051f9cd00d861391"; } } @@ -1341,7 +1341,7 @@ export class ofPlace$dyns_Tri { } typeId$Any(): rs.TypeId { - return "db6a2678079cd6de1063f521a32772c0"; + return "1efc30ab591c39470b121f4a2de91e05"; } } @@ -1353,7 +1353,7 @@ export class ofPlace$ids_Mood { } typeId$Any(): rs.TypeId { - return "180954c559d9dbe8afcd63c1da176c31"; + return "586c02dbd458954a051f9cd00d861391"; } } diff --git a/ts/fixtures/lang/panics/hook/expected/lib.ts b/ts/fixtures/lang/panics/hook/expected/lib.ts index e45940e1c..d09fe4c1a 100644 --- a/ts/fixtures/lang/panics/hook/expected/lib.ts +++ b/ts/fixtures/lang/panics/hook/expected/lib.ts @@ -81,7 +81,7 @@ export class of$panics_Point { } typeId$Any(): rs.TypeId { - return "37e450afe4d41be326161cb6b122df94"; + return "aaa20389e9fe41bd0cc25c34c599ea28"; } } From eca1fa7771945addd9247b426f16f6c91cc10d84 Mon Sep 17 00:00:00 2001 From: quest fixer Date: Fri, 6 Nov 2026 21:56:02 -0800 Subject: [PATCH 10/10] test(ts): regenerate TypeId snapshots without incremental compilation --- ts/fixtures/lang/dyns/expected/ids.ts | 14 +++++++------- ts/fixtures/lang/dyns/expected/lib.ts | 14 +++++++------- ts/fixtures/lang/panics/hook/expected/lib.ts | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ts/fixtures/lang/dyns/expected/ids.ts b/ts/fixtures/lang/dyns/expected/ids.ts index e04893018..c637605f5 100644 --- a/ts/fixtures/lang/dyns/expected/ids.ts +++ b/ts/fixtures/lang/dyns/expected/ids.ts @@ -42,12 +42,12 @@ export function idOfVal$dyn_Any(_1: Any.Any): rs.TypeId { /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$dyn_ids_Marked(_1: Marked.Marked): rs.TypeId { - return "3bbda84d3ea87978c3191a064aa30838"; + return "d356aeac368968f265dedab8a8d72ad8"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ export function idOfVal$ids_Mood(_1: Mood.Mood): rs.TypeId { - return "586c02dbd458954a051f9cd00d861391"; + return "328e59b82c6cb0a6eb720af972265604"; } /** The `TypeId` of what `x` is, through a type parameter that may be a trait object. */ @@ -116,8 +116,8 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou mood = "Calm" as Mood.Mood; } const byte: Byte.Byte = { _0: b }; - const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "47cf44edf6d848167c2724f9fe31a15d", "586c02dbd458954a051f9cd00d861391", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "3bbda84d3ea87978c3191a064aa30838", "25ff997ce0b3a76fb5ce30b55accc57f"]; - const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "cfb1622e7734f8af272d8d182905dc25", "47cf44edf6d848167c2724f9fe31a15d", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "47cf44edf6d848167c2724f9fe31a15d", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; + const ids: rs.TypeId[] = ["cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "8f5d7517f5a241dab4213252fd0d53e8", "328e59b82c6cb0a6eb720af972265604", "24c161f26c70c1f1b9f602dc5fe9f65c", "b7381ee5f3fdfc9d7fa709f37e151622", "05fc01408e45e7cddf9e041e3391eafc", "3801bd64778907c7633cf473fe556a70", "513ce68a38c017b0c2e73410455cb3b0", "f48384178e2341267f2bcf8f82c035ac", "37a732caafaf8e089d3a9d4c07b2ec78", "d356aeac368968f265dedab8a8d72ad8", "25ff997ce0b3a76fb5ce30b55accc57f"]; + const found: rs.TypeId[] = [idOf$u8(), "cfb1622e7734f8af272d8d182905dc25", "cfb1622e7734f8af272d8d182905dc25", "8f5d7517f5a241dab4213252fd0d53e8", "cfb1622e7734f8af272d8d182905dc25", "79f19461b401588885a89e43144b08f1", "8f5d7517f5a241dab4213252fd0d53e8", idOfVal$str("str"), idOfVal$ids_Mood(mood), idOfVal$dyn_Any(new of$u8(a)), idOf$Option_u8()]; const iter: rs.Iter = rs.iterSlice(found); while (true) { const _53: rs.TypeId | rs.Done = iter.next(); @@ -168,7 +168,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou return i5 === _165.typeId$Any(); }); const _187: boolean = _165.typeId$Any() === any.typeId$Any(); - const _193: boolean = idOfVal$dyn_ids_Marked(_165) === "3bbda84d3ea87978c3191a064aa30838"; + const _193: boolean = idOfVal$dyn_ids_Marked(_165) === "d356aeac368968f265dedab8a8d72ad8"; const args43 = [(f: rs.Formatter) => rs.u8Display(_178, f), (f: rs.Formatter) => rs.fmtOption(_180, f, rs.usizeDebug), (f: rs.Formatter) => rs.fmtBool(_187, f), (f: rs.Formatter) => rs.fmtBool(_193, f)]; put(out, rs.fmtFormat([args43[0], " ", args43[1], " ", args43[2], " ", args43[3], " "]).v); } @@ -196,7 +196,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _259: rs.Arc = new rs.Arc(byte); const shared: rs.Arc = new rs.ArcDyn(_259, new of$ids_Byte(_259.value)); const boxed: Marked.Marked = new of$u8(a); - const _270: boolean = shared.value.typeId$Any() === "47cf44edf6d848167c2724f9fe31a15d"; + const _270: boolean = shared.value.typeId$Any() === "8f5d7517f5a241dab4213252fd0d53e8"; const _278: boolean = "6864f1ad0ca168ae5e502d6898f6f9c3" === "6864f1ad0ca168ae5e502d6898f6f9c3"; const _285: boolean = boxed.typeId$Any() === "cfb1622e7734f8af272d8d182905dc25"; const args45 = [(f: rs.Formatter) => rs.fmtBool(_270, f), (f: rs.Formatter) => rs.fmtBool(_278, f), (f: rs.Formatter) => rs.fmtBool(_285, f)]; @@ -349,7 +349,7 @@ export function ids(dataData: Uint8Array, dataStart: number, dataLen: number, ou const _580: rs.usize = rs.hashLen(hashed); const args57 = [(f: rs.Formatter) => rs.fmtBool(ordered, f), (f: rs.Formatter) => rs.usizeDisplay(_577, f), (f: rs.Formatter) => rs.usizeDisplay(_580, f)]; put(out, rs.fmtFormat([args57[0], " ", args57[1], " ", args57[2], " "]).v); - const _590: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["47cf44edf6d848167c2724f9fe31a15d", "byte"] as [rs.TypeId, string], ["586c02dbd458954a051f9cd00d861391", "mood"] as [rs.TypeId, string]]); + const _590: rs.Iter<[rs.TypeId, string]> = rs.iterSlice([["cfb1622e7734f8af272d8d182905dc25", "u8"] as [rs.TypeId, string], ["8f5d7517f5a241dab4213252fd0d53e8", "byte"] as [rs.TypeId, string], ["328e59b82c6cb0a6eb720af972265604", "mood"] as [rs.TypeId, string]]); const names: rs.HashMap = rs.hashExtend(rs.hashNew(rs.hashing(rs.typeIdHash, rs.same)) as rs.HashMap, _590, undefined, undefined, undefined, 58720256); for (const _603 of boxes.items) { const part8 = rs.hashGet(names, _603.typeId$Any()); diff --git a/ts/fixtures/lang/dyns/expected/lib.ts b/ts/fixtures/lang/dyns/expected/lib.ts index 727b91997..28cc47b27 100644 --- a/ts/fixtures/lang/dyns/expected/lib.ts +++ b/ts/fixtures/lang/dyns/expected/lib.ts @@ -583,7 +583,7 @@ export class of$dyns_Noisy { } typeId$Any(): rs.TypeId { - return "16a5b7dad13abb2368cccd1d4411ed29"; + return "8abb48f5c9ad521e17c8b05ce0f1d679"; } } @@ -659,7 +659,7 @@ export class of$dyns_Square { } typeId$Any(): rs.TypeId { - return "2bc6a9a6ddabf1ab5bf7f2ef98b9915f"; + return "0ba6291209e997830eaef6cade61afd2"; } } @@ -751,7 +751,7 @@ export class of$dyns_Tri { } typeId$Any(): rs.TypeId { - return "1efc30ab591c39470b121f4a2de91e05"; + return "66772eb3554749a10355c03efd41f5ad"; } } @@ -859,7 +859,7 @@ export class of$ids_Byte { } typeId$Any(): rs.TypeId { - return "47cf44edf6d848167c2724f9fe31a15d"; + return "8f5d7517f5a241dab4213252fd0d53e8"; } } @@ -871,7 +871,7 @@ export class of$ids_Mood { } typeId$Any(): rs.TypeId { - return "586c02dbd458954a051f9cd00d861391"; + return "328e59b82c6cb0a6eb720af972265604"; } } @@ -1341,7 +1341,7 @@ export class ofPlace$dyns_Tri { } typeId$Any(): rs.TypeId { - return "1efc30ab591c39470b121f4a2de91e05"; + return "66772eb3554749a10355c03efd41f5ad"; } } @@ -1353,7 +1353,7 @@ export class ofPlace$ids_Mood { } typeId$Any(): rs.TypeId { - return "586c02dbd458954a051f9cd00d861391"; + return "328e59b82c6cb0a6eb720af972265604"; } } diff --git a/ts/fixtures/lang/panics/hook/expected/lib.ts b/ts/fixtures/lang/panics/hook/expected/lib.ts index d09fe4c1a..b72d52964 100644 --- a/ts/fixtures/lang/panics/hook/expected/lib.ts +++ b/ts/fixtures/lang/panics/hook/expected/lib.ts @@ -81,7 +81,7 @@ export class of$panics_Point { } typeId$Any(): rs.TypeId { - return "aaa20389e9fe41bd0cc25c34c599ea28"; + return "8e48006f0a085ab0ca68bcd6079f396f"; } }