From 903527a5003ebaa6b17c8e373cd43f54c52ea748 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:19:14 -0800 Subject: [PATCH 01/10] chore(quest): claim quest/m3/ts-runtime-throws.md Quest-Claim: a624b21b70dbf7b2 From e34b9dfec71ad39ff250baf3fe5b88830c027c18 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 14:36:51 -0800 Subject: [PATCH 02/10] feat(ts): abort as std's precondition checks where Rust leaves behavior undefined, and locate zip's and tokio's panics A read or write through a pointer to no memory, a write through str::as_ptr, Arc::from_raw of a pointer no into_raw gave or of a dropped value, and dealloc or realloc of memory alloc didn't give now abort with std's "unsafe precondition(s) violated" wording rather than a rust2-ts error. A hook program now locates std's Zip::next_back unreachable!() and tokio's oneshot "called after complete", checked against native. Co-Authored-By: Claude Opus 5.5 --- ts/Cargo.lock | 1 + ts/README.md | 6 +- ts/fixtures/lang/panics/Cargo.toml | 5 +- ts/fixtures/lang/panics/caller.ts | 8 +- .../lang/panics/hook/expected/hooked.Short.ts | 31 ++++ .../lang/panics/hook/expected/hooked.ts | 169 +++++++++++------- ts/fixtures/lang/panics/hook/expected/lib.ts | 6 +- .../tokio/sync/oneshot/error.RecvError.ts | 12 ++ ts/fixtures/lang/panics/src/hooked.rs | 46 ++++- ts/fixtures/lang/panics/src/lib.rs | 1 + ts/runtime/rs.ts | 40 +++-- ts/runtime/rs/alloc.ts | 4 +- ts/runtime/rs/collections.ts | 3 +- ts/runtime/rs/iter.ts | 7 +- ts/runtime/rs/task.ts | 10 +- ts/runtime/rs/tokio.ts | 2 +- ts/src/lower/caller.rs | 61 +++++-- ts/tests/pointers.ts | 36 ++-- 18 files changed, 310 insertions(+), 138 deletions(-) create mode 100644 ts/fixtures/lang/panics/hook/expected/hooked.Short.ts create mode 100644 ts/fixtures/lang/panics/hook/expected/tokio/sync/oneshot/error.RecvError.ts diff --git a/ts/Cargo.lock b/ts/Cargo.lock index 2c61d6bac..37c56ffb4 100644 --- a/ts/Cargo.lock +++ b/ts/Cargo.lock @@ -387,6 +387,7 @@ version = "0.0.0" dependencies = [ "bytes", "edition2018", + "tokio", ] [[package]] diff --git a/ts/README.md b/ts/README.md index dfb3a7e0b..2e45269bc 100644 --- a/ts/README.md +++ b/ts/README.md @@ -110,7 +110,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `Vec` | `rs.Vec`: its items, the array `items`, and the capacity std's holds; `rs.vecFrom(items)` makes one of an array with room for exactly them. `rs.ByteVec` of bytes | | `Cow<[T]>`, `Cow` | `rs.Cow`: the `Vec` it owns, or an `rs.Borrowed` holding the slice it borrows, `rs.Cow>` holding the arrays of a slice of arrays; `rs.ByteCow` for bytes, an `rs.ByteVec` or an `rs.ByteSlice`; `rs.StrCow` for text, the `rs.String` it owns or an `rs.Borrowed` holding the string it borrows, whose text `rs.strCowStr` reads | | `&T`, `&mut T`, `Box`, `Reverse`, `NonZero`, `AssertUnwindSafe` | the value; a `&mut` to a value JS copies, such as a number, an `Option`, or a reference, or to an `Arc`, a `Waker`, or a `LocalKey`, whose copies share what it points at, is an `rs.Place`, which for what a box holds is the place holding the box | -| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write, or a mutable slice, through it, which Rust forbids, fails at run time, as do a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rs.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | +| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling, a read or write through either of which, or through a pointer arithmetic moved off either, aborts, as Rust leaves it undefined. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write, or a mutable slice, through it, which Rust leaves undefined, aborts, as std's debug checks of unsafe preconditions do, while a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers fail at run time, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rs.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | | `MaybeUninit` | `T`: `undefined` until written, `0` for a byte, or an object whose parts kept as objects are there, holding `undefined`, as `Box::new_uninit` and each of `Box::new_uninit_slice`'s is; a slice's `write_clone_of_slice` clones into its slots without dropping what they held. `Box::new_zeroed`'s holds the value of zero bytes in each part they are one of, such as a number, `false`, `None`, a null pointer, or an enum's variant of a tag or niche of zero, and `undefined` in each part they are none of, such as a reference, for a write to fill before a read | | `ManuallyDrop` | `T`, which nothing drops but its own `drop`; its `Debug`, comparisons, and constants are refused | | `union` | an object of slots named by offset, `at0` and `at8`, each holding the field part kept there; fields must overlap in the same type, or in a non-null pointer and an `Option` of it | @@ -123,7 +123,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `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 | +| `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, and abort on memory `alloc` didn't give, as Rust leaves that undefined; 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 | @@ -136,7 +136,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `static` | a module's value, named for the static, that every use shares, read from the memory rustc evaluated; one that reads another static or a class is an `rs.LazyCell` of it, made on first use, since that may not be made yet when its module is. A `static mut`, and a pointer in one into memory the translation can't name, fail translation | | a type that drops | a class with `[Symbol.dispose]`: its `Drop` impl, then its fields | | a type's function | a function of the type's module, taking `self` first: `Decoder.slice(dec, 4)` after `import * as Decoder` | -| `Arc`, `Rc`, `Weak`, `Mutex` | `rs.Arc` for either, of what a `Box` is for a slice or `str`, with its strong and weak counts, an `Arc<[T; N]>` unsized to an `Arc<[T]>` an `rs.ArcDyn` of the slice of its array, sharing its count, an `Arc<[u8]>` of an `Arc`'s bytes sharing its count, and `new_cyclic`'s `Weak` upgrading only once its value is made, `get_mut` lending its value only while no other `Arc` or `Weak` shares it, `make_mut` cloning it into a new `rs.Arc` while another `Arc` shares it, or moving it there while only `Weak`s do, which then dangle, as a copy where pointers to it compare, `as_ptr` and `into_raw` pointing where a reference to its value does, or at its place where JS copies it, as a pointer the body shows made from a reference to that value does, which `from_raw`, `increment_strong_count`, and `decrement_strong_count` take back to its `rs.Arc` and count, refused for one the body shows a borrow made, and failing at run time on another pointer no `as_ptr` or `into_raw` of that type of `Arc` gave, or one whose value dropped, and refused for one to a slice or bytes, which JS makes anew each time, and `ptr::addr_eq` comparing what `ptr::eq` compares, of one pointee type, and `into_inner` giving it only from the last strong `Arc`, after which its `Weak`s no longer upgrade; `rs.Weak`, counted in its `rs.Arc` until it drops, and of no `Arc` once made by `Weak::new`; `rs.Mutex`, its own guard, which a lock gives as `Ok` and the guard's drop unlocks: locking it again while held panics and `try_lock` gives `WouldBlock`, as wasm32's do, and a guard's `map` and `filter_map` make `rs.MutexMap`s, each where the part it lends is, which hold the mutex locked until they drop, and a panic aborts, so nothing poisons it and `thread::panicking` is `false`; a `Mutex`'s, a `RefCell`'s, and an `RwLock`'s `into_inner` gives its value and `get_mut` lends it, or an `rs.Place` of it where JS copies it | +| `Arc`, `Rc`, `Weak`, `Mutex` | `rs.Arc` for either, of what a `Box` is for a slice or `str`, with its strong and weak counts, an `Arc<[T; N]>` unsized to an `Arc<[T]>` an `rs.ArcDyn` of the slice of its array, sharing its count, an `Arc<[u8]>` of an `Arc`'s bytes sharing its count, and `new_cyclic`'s `Weak` upgrading only once its value is made, `get_mut` lending its value only while no other `Arc` or `Weak` shares it, `make_mut` cloning it into a new `rs.Arc` while another `Arc` shares it, or moving it there while only `Weak`s do, which then dangle, as a copy where pointers to it compare, `as_ptr` and `into_raw` pointing where a reference to its value does, or at its place where JS copies it, as a pointer the body shows made from a reference to that value does, which `from_raw`, `increment_strong_count`, and `decrement_strong_count` take back to its `rs.Arc` and count, refused for one the body shows a borrow made, and aborting, as std's debug checks of unsafe preconditions do, on another pointer no `as_ptr` or `into_raw` of that type of `Arc` gave, or one whose value dropped, which Rust leaves undefined, and refused for one to a slice or bytes, which JS makes anew each time, and `ptr::addr_eq` comparing what `ptr::eq` compares, of one pointee type, and `into_inner` giving it only from the last strong `Arc`, after which its `Weak`s no longer upgrade; `rs.Weak`, counted in its `rs.Arc` until it drops, and of no `Arc` once made by `Weak::new`; `rs.Mutex`, its own guard, which a lock gives as `Ok` and the guard's drop unlocks: locking it again while held panics and `try_lock` gives `WouldBlock`, as wasm32's do, and a guard's `map` and `filter_map` make `rs.MutexMap`s, each where the part it lends is, which hold the mutex locked until they drop, and a panic aborts, so nothing poisons it and `thread::panicking` is `false`; a `Mutex`'s, a `RefCell`'s, and an `RwLock`'s `into_inner` gives its value and `get_mut` lends it, or an `rs.Place` of it where JS copies it | | `PoisonError`, `TryLockError` | the `T` it holds; `rs.TryLockError`, tagged as `Bound` is | | `Cell`, `UnsafeCell`, `RefCell`, `RwLock` | `rs.Cell`, the place holding its value in `v`, for either of the first two: `UnsafeCell::get`'s and `Cell::as_ptr`'s pointer, and `get_mut`'s reference, is the cell where it is an `rs.Place`, and otherwise the object in `v`, refused where the crate may put another cell or object in its place; `rs.RefCell` for either of the others, its own guard, counting its borrows: borrowing it while that conflicts panics as `RefCell`'s does, and locking it so aborts as wasm32's `RwLock` does; `try_borrow` and `try_borrow_mut` fail with `rs.BorrowError` and `rs.BorrowMutError` instead, a clone borrows the cell, `Ref::clone` counts another borrow of it, and a guard's `map`, `filter_map`, `try_map`, and `map_split`, an `RwLock` guard's included, make `rs.RefMap`s, each where a part it lends is, which a write through a mapped `RefMut` reaches in place, sharing the cell's borrow until the last drops; `RwLockWriteGuard::downgrade` keeps the lock as one read, and `Ref::leak` and `RefMut::leak` keep the borrow until `RefCell::undo_leak` ends it; `Cell::update` calls its function on a copy, and `RefCell::replace_with` on the value, borrowed as `borrow_mut` does, or its place where JS copies it; refused for a part of a sized type JS can't write in place, such as a binding's | | `thread_local!`, `LocalKey` | an `rs.LocalKey`, a module's value that each copy of the key is, which makes its value on first use from the `const` or the expression and never drops it, as wasm32's do; `with` calls its function on that value, `try_with` never fails, the `Cell` and `RefCell` helpers lower from std, and a `RefCell` key's `set` and `with_borrow_mut` borrow it as `borrow_mut` does | diff --git a/ts/fixtures/lang/panics/Cargo.toml b/ts/fixtures/lang/panics/Cargo.toml index 40fe27438..b75c4c315 100644 --- a/ts/fixtures/lang/panics/Cargo.toml +++ b/ts/fixtures/lang/panics/Cargo.toml @@ -12,12 +12,13 @@ crate-type = ["lib", "cdylib"] [features] # Adds the cases that set a panic hook, which has the translation give every panic its -# location: the other shape of its output. `bytes`' panics are among them. -hook = ["dep:bytes"] +# location: the other shape of its output. `bytes`' and tokio's panics are among them. +hook = ["dep:bytes", "dep:tokio"] [dependencies] bytes = { version = "1.12.1", optional = true } edition2018 = { path = "edition2018" } +tokio = { version = "1.54.1", default-features = false, features = ["sync"], optional = true } [lints] workspace = true diff --git a/ts/fixtures/lang/panics/caller.ts b/ts/fixtures/lang/panics/caller.ts index 09caea6c5..090d62d18 100644 --- a/ts/fixtures/lang/panics/caller.ts +++ b/ts/fixtures/lang/panics/caller.ts @@ -1,8 +1,14 @@ -// What `panics`' hooks wrote, which `differential.ts` compares after each case. +// What `panics`' hooks wrote, which `differential.ts` compares after each case, and the +// inputs its cases name, which run with the generated ones. +import { ops } from "./lang.ts"; import { note as noted } from "./lib.ts"; export { ops, run } from "./lang.ts"; /** What the hooks wrote since the last call, as a JS string. */ export const note = (): string => noted().v; + +/** Each of std's sites `hooked::sited` panics at, by kind, which random inputs may miss, where a hook is set. */ +const sited = ops.get("hooked::sited"); +export const cases: Uint8Array[] = sited === undefined ? [] : Array.from({ length: 87 }, (_, kind) => Uint8Array.of(...sited, kind, 1)); diff --git a/ts/fixtures/lang/panics/hook/expected/hooked.Short.ts b/ts/fixtures/lang/panics/hook/expected/hooked.Short.ts new file mode 100644 index 000000000..7a0a34eed --- /dev/null +++ b/ts/fixtures/lang/panics/hook/expected/hooked.Short.ts @@ -0,0 +1,31 @@ +// Generated by rust2-ts. Do not edit. + +import * as rs from "./rs.ts"; + +/** + * An iterator of one item fewer than the length it says, which a zip from the back finds + * short. + */ +export interface Short { + _0: rs.u8; +} + +export function next$iter_Iterator(self: Short): rs.u8 | rs.Done { + return rs.iterFromOption(nextBack$iter_DoubleEndedIterator(self)); +} + +export function sizeHint$iter_Iterator(self: Short): [rs.usize, rs.usize | undefined] { + const len: rs.usize = rs.usizeAdd(self._0 as rs.usize, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 439, col: 19 }); + return [len, len] as [rs.usize, rs.usize | undefined]; +} + +export function nextBack$iter_DoubleEndedIterator(self: Short): rs.u8 | undefined { + const _2: rs.u8 | undefined = rs.u8CheckedSub(self._0, 1); + if (_2 !== undefined) { + self._0 = _2; + return self._0; + } + return undefined; +} + +//# sourceMappingURL=hooked.Short.ts.map diff --git a/ts/fixtures/lang/panics/hook/expected/hooked.ts b/ts/fixtures/lang/panics/hook/expected/hooked.ts index ca8228fc8..c096e8213 100644 --- a/ts/fixtures/lang/panics/hook/expected/hooked.ts +++ b/ts/fixtures/lang/panics/hook/expected/hooked.ts @@ -11,8 +11,10 @@ import { map$1hfd4x1 as result_map$1hfd4x1, unwrapOrDefault$0t7trfe as result_un import { panicked as edition2018_panicked } from "./edition2018.ts"; import * as Failing from "./hooked.Failing.ts"; import * as Lying from "./hooked.Lying.ts"; +import * as Short from "./hooked.Short.ts"; import * as Shown from "./hooked.Shown.ts"; import { withBorrow$097wfl1 } from "./std/thread/local.ts"; +import type * as oneshot_error_RecvError from "./tokio/sync/oneshot/error.RecvError.ts"; /** * Write what `info` says: its `Display`, its payload's type and text, a `String` payload's @@ -85,7 +87,7 @@ export function hook(): void { captured(info); }, (): void => { rs.drop(captured); - }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); + }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); } export function tracked(n: rs.u8, caller: rs.Location): rs.u8 { @@ -218,7 +220,7 @@ export function aborted(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void } }, (): void => { rs.drop(captured2); - }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); + }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); rs.byteVecPush(out, n); const _13: rs.u8 = rs.u8Rem(kind, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 174, col: 11 }); if (_13 === 3 || _13 === 4) { @@ -257,7 +259,7 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { const _19: rs.u16[] = [n as rs.u16]; const set: rs.BTreeSet = rs.btreeExtendKeys(rs.btreeNew(rs.cmp) as rs.BTreeSet, rs.iterSlice(_19), true, undefined, undefined, 2, true); b0: { - const k: rs.u8 = rs.u8Rem(kind, 86, { file: "fixtures/lang/panics/src/hooked.rs", line: 198, col: 11 }); + const k: rs.u8 = rs.u8Rem(kind, 87, { file: "fixtures/lang/panics/src/hooked.rs", line: 198, col: 11 }); if (k === 0) { rs.byteVecPush(out, rs.byteVecWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 199, col: 48 })).length & 0xff); } else if (k === 1) { @@ -276,23 +278,23 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.byteVecPush(out, rs.charEncodeUtf16(_62, rs.sliceFrom(_69)).length & 0xff); } else if (k === 7) { const _73: [rs.RangeBound, rs.RangeBound] = [{ tag: "Excluded", _0: n as rs.u16 } as rs.RangeBound, { tag: "Excluded", _0: n as rs.u16 } as rs.RangeBound]; - rs.iterExtendBytes(out, rs.iterMap(rs.btreeRange(map, _73), (_244: [rs.u16, rs.u8]): rs.u8 => { - return _244[1]; + rs.iterExtendBytes(out, rs.iterMap(rs.btreeRange(map, _73), (_250: [rs.u16, rs.u8]): rs.u8 => { + return _250[1]; }), "next"); } else if (k === 8) { const _81: rs.Range = new rs.Range(rs.u16Add(n as rs.u16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 215, col: 35 }), n as rs.u16); - rs.iterExtendBytes(out, rs.iterMap(rs.btreeRange(map, _81), (_239: [rs.u16, rs.u8]): rs.u8 => { - return _239[1]; + rs.iterExtendBytes(out, rs.iterMap(rs.btreeRange(map, _81), (_244: [rs.u16, rs.u8]): rs.u8 => { + return _244[1]; }), "next"); } else if (k === 9) { const _89: [rs.RangeBound, rs.RangeBound] = [{ tag: "Excluded", _0: n as rs.u16 } as rs.RangeBound, { tag: "Excluded", _0: n as rs.u16 } as rs.RangeBound]; - rs.iterExtendBytes(out, rs.iterMap(rs.btreeRangeKeys(set, _89), (_237: rs.u16): rs.u8 => { - return _237 & 0xff; + rs.iterExtendBytes(out, rs.iterMap(rs.btreeRangeKeys(set, _89), (_239: rs.u16): rs.u8 => { + return _239 & 0xff; }), "next"); } else if (k === 10) { const _97: rs.Range = new rs.Range(rs.u16Add(n as rs.u16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 220, col: 36 }), n as rs.u16); - rs.iterExtendBytes(out, rs.iterMap(rs.btreeRangeKeys(set, _97), (_232: rs.u16): rs.u8 => { - return _232 & 0xff; + rs.iterExtendBytes(out, rs.iterMap(rs.btreeRangeKeys(set, _97), (_237: rs.u16): rs.u8 => { + return _237 & 0xff; }), "next"); } else if (k === 11) { rs.dequeInsert(rs.dequeClone(deque), rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 221, col: 36 }), n); @@ -398,8 +400,8 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { undefined; })); })(EXCLUSIVE.get()); - withBorrow$097wfl1(EXCLUSIVE, (_217: rs.u8): undefined => { - rs.byteVecPush(out, _217); + withBorrow$097wfl1(EXCLUSIVE, (_225: rs.u8): undefined => { + rs.byteVecPush(out, _225); }); } else if (k === 35) { const _277: rs.ByteVec = rs.byteVecFrom(rs.byteVecView(v)); @@ -443,13 +445,13 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { } else if (k === 47) { const _365: rs.ByteVec = rs.byteVecFrom(rs.byteVecView(v)); const _367: rs.RangeFrom = new rs.RangeFrom(rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 306, col: 47 }), rs.usizeStep); - rs.iterExtendBytes(out, rs.byteVecExtractIf(_365, _367, (_210: rs.Place): boolean => { + rs.iterExtendBytes(out, rs.byteVecExtractIf(_365, _367, (_217: rs.Place): boolean => { return true; }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/extract_if.rs", line: 43, col: 36 }), "next"); } else if (k === 48) { const _374: rs.Vec = rs.vecFrom([n as rs.u16]); const _377: { end: rs.usize } = { end: rs.usizeAdd(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 307, col: 56 }) }; - rs.byteVecPush(out, rs.ownedCount(rs.vecExtractIfMut(_374, _377, (_29: rs.Place): boolean => { + rs.byteVecPush(out, rs.ownedCount(rs.vecExtractIfMut(_374, _377, (_210: rs.Place): boolean => { return true; }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/extract_if.rs", line: 43, col: 36 }), undefined, undefined) & 0xff); } else if (k === 49) { @@ -513,8 +515,8 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { } else if (k === 78) { rs.vecInsert(rs.vecFrom([n as rs.u16]), rs.usizeAdd(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 348, col: 41 }), 0, { file: "fixtures/lang/panics/src/hooked.rs", line: 348, col: 34 }); } else if (k === 79) { - rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(rs.vecSplitOff(rs.vecFrom([n as rs.u16]), rs.usizeAdd(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 349, col: 55 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 349, col: 45 }).items), (_2: rs.u16): rs.u8 => { - return _2 & 0xff; + rs.iterExtendBytes(out, rs.iterMap(rs.iterSlice(rs.vecSplitOff(rs.vecFrom([n as rs.u16]), rs.usizeAdd(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 349, col: 55 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 349, col: 45 }).items), (_29: rs.u16): rs.u8 => { + return _29 & 0xff; }), undefined, true); } else if (k === 80) { const _550: rs.ByteSlice = rs.byteVecSlice(rs.byteVecFrom(rs.byteVecView(v))); @@ -530,6 +532,8 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { } else if (k === 84) { const _585: Failing.Failing = {}; rs.byteVecExtendFromSlice(out, rs.stringAsBytes(rs.fmtToString((f: rs.Formatter) => Failing.fmt$fmt_Display(_585, f)).v)); + } else if (k === 85) { + rs.byteVecPush(out, rs.iterFrom({ _0: n }, Lying.next$iter_Iterator, undefined, { hint: Lying.sizeHint$iter_Iterator }).len() & 0xff); } else { if (53 <= k) { if (k <= 56) { @@ -543,7 +547,11 @@ export function sited(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { break b0; } } - rs.byteVecPush(out, rs.iterFrom({ _0: n }, Lying.next$iter_Iterator, undefined, { hint: Lying.sizeHint$iter_Iterator }).len() & 0xff); + const _593: Short.Short = { _0: rs.u8Rem(n, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 356, col: 31 }) }; + const _596: rs.Range = new rs.Range(0, rs.u8Add(rs.u8Rem(n, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 356, col: 45 }), 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 356, col: 45 })); + rs.iterExtendBytes(out, rs.iterMap(rs.iterRev(rs.iterZip(rs.iterFrom(_593, Short.next$iter_Iterator, undefined, { hint: Short.sizeHint$iter_Iterator, back: (it: Short.Short) => rs.iterFromOption(Short.nextBack$iter_DoubleEndedIterator(it)) }), _596)), (_2: [rs.u8, rs.u8]): rs.u8 => { + return _2[0] ^ _2[1]; + }), "next"); } } } @@ -557,16 +565,16 @@ export function joined(kind: rs.u8, n: rs.u8, out: rs.ByteVec): void { let joined!: rs.ByteVec; const big: rs.ByteVec = rs.byteVecOf(n, 1 << 16); const refs: (a0: rs.usize) => rs.Vec = (count: rs.usize): rs.Vec => { - return rs.vecFromElem(rs.byteSliceRange(rs.byteVecSlice(big), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 373, col: 40 }), count, undefined); + return rs.vecFromElem(rs.byteSliceRange(rs.byteVecSlice(big), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 374, col: 40 }), count, undefined); }; if (kind === 0) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 375, col: 19 })).items)); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 376, col: 19 })).items)); } else if (kind === 1) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 376, col: 19 })).items), rs.byteSliceFrom(Uint8Array.of(n))); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 16, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 377, col: 19 })).items), rs.byteSliceFrom(Uint8Array.of(n))); } else if (kind === 2) { - joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 15, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 377, col: 19 })).items)); + joined = rs.byteSlicesJoin(rs.sliceFrom(refs(rs.usizeAdd(1 << 15, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 378, col: 19 })).items)); } else { - joined = rs.iterToByteVec(rs.iterMap(rs.iterSlice(rs.slicesJoin(rs.sliceFrom(rs.vecFromElem(rs.sliceFrom(rs.vecFromElem(n as rs.u16, 1 << 16, undefined).items), rs.usizeAdd(1 << 14, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 380, col: 42 }), undefined).items), 2, rs.sliceFrom([1])).items), (_2: rs.u16): rs.u8 => { + joined = rs.iterToByteVec(rs.iterMap(rs.iterSlice(rs.slicesJoin(rs.sliceFrom(rs.vecFromElem(rs.sliceFrom(rs.vecFromElem(n as rs.u16, 1 << 16, undefined).items), rs.usizeAdd(1 << 14, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 381, col: 42 }), undefined).items), 2, rs.sliceFrom([1])).items), (_2: rs.u16): rs.u8 => { return _2 & 0xff; }), undefined, true); } @@ -589,10 +597,10 @@ export function compared(kind: rs.u8, n: rs.u8): rs.u8 { const _5: [rs.RefCell, rs.RefCell] = [new rs.RefCell(n), new rs.RefCell(rs.u8WrappingAdd(n, 1))]; const a: rs.RefCell = _5[0]; const b: rs.RefCell = _5[1]; - if (!(rs.u8Rem(n, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 392, col: 20 }) === 0)) { - _held = rs.refCellBorrowMut(b, { file: "fixtures/lang/panics/src/hooked.rs", line: 392, col: 59 }); + if (!(rs.u8Rem(n, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 393, col: 20 }) === 0)) { + _held = rs.refCellBorrowMut(b, { file: "fixtures/lang/panics/src/hooked.rs", line: 393, col: 59 }); } else { - _held = rs.refCellBorrowMut(a, { file: "fixtures/lang/panics/src/hooked.rs", line: 392, col: 35 }); + _held = rs.refCellBorrowMut(a, { file: "fixtures/lang/panics/src/hooked.rs", line: 393, col: 35 }); } if (kind === 0) { _0 = rs.refCellBy(rs.same, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell.rs", line: 1482, col: 15 }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell.rs", line: 1482, col: 34 })(a, b) ? 1 : 0; @@ -639,11 +647,11 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { const at: rs.usize = n as rs.usize; const whole: rs.ByteSlice = rs.bytesFromVec(rs.byteVecOf(n, 4)); b0: { - const k: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 434, col: 24 }); + const k: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 461, col: 24 }); if (0 <= k) { if (k <= 1) { rs.setHook((info: rs.PanicHookInfo): undefined => { - const at2: rs.Location = rs.optionUnwrap(info.location, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 436, col: 38 }); + const at2: rs.Location = rs.optionUnwrap(info.location, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 38 }); const _10: string = at2.file; const _126: rs.u32 = at2.line; const _14: rs.u32 = at2.col; @@ -652,16 +660,16 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.localKeyWithBorrowMut(NOTE, (note: rs.String): undefined => { rs.stringPushStr(note, line.v); }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/thread/local.rs", line: 721, col: 38 }); - rs.panicFmt(["unread"], { file: "fixtures/lang/panics/src/hooked.rs", line: 439, col: 13 }); - }, { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); + rs.panicFmt(["unread"], { file: "fixtures/lang/panics/src/hooked.rs", line: 466, col: 13 }); + }, { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); const subset: rs.ByteSlice = rs.bytesSlice(whole, 0, 1); if (k === 0) { - const _22: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(1, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 443, col: 34 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 443, col: 30 })); + const _22: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(1, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 34 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 30 })); held = rs.bytesSliceRef(_22, subset); rs.bytesDrop(_22); } else { const _32: rs.ByteSlice = rs.bytesSlice(whole, 0, 1); - const _35: rs.ByteSlice = rs.byteSliceRange(whole, 0, rs.usizeAdd(2, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 444, col: 58 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 444, col: 54 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 444, col: 51 }); + const _35: rs.ByteSlice = rs.byteSliceRange(whole, 0, rs.usizeAdd(2, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 471, col: 58 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 471, col: 54 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 471, col: 51 }); held = rs.bytesSliceRef(_32, _35); rs.bytesDrop(_32); } @@ -673,38 +681,38 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { } } hook(); - const shared: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(rs.byteSliceFrom(rs.bytes(8).fill(n)), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 450, col: 44 })); - const _52: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 451, col: 11 }); + const shared: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(rs.byteSliceFrom(rs.bytes(8).fill(n)), 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 477, col: 44 })); + const _52: rs.u8 = rs.u8Rem(kind, 33, { file: "fixtures/lang/panics/src/hooked.rs", line: 478, col: 11 }); if (_52 === 2) { - const _56: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 452, col: 49 }), 2); + const _56: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 479, col: 49 }), 2); rs.byteVecExtendFromSlice(out, _56); rs.bytesDrop(_56); } else if (_52 === 3) { - const _63: rs.ByteSlice = rs.bytesSlice(whole, 0, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 453, col: 51 })); + const _63: rs.ByteSlice = rs.bytesSlice(whole, 0, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 480, col: 51 })); rs.byteVecExtendFromSlice(out, _63); rs.bytesDrop(_63); } else if (_52 === 4) { - const _72: rs.RangeInclusive = new rs.RangeInclusive(rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 454, col: 62 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 454, col: 49 }), 4294967295, rs.usizeStep); + const _72: rs.RangeInclusive = new rs.RangeInclusive(rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 62 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 49 }), 4294967295, rs.usizeStep); const _70: rs.ByteSlice = rs.bytesSliceInclusive(whole, _72); rs.byteVecExtendFromSlice(out, _70); rs.bytesDrop(_70); } else if (_52 === 5) { let _81: rs.ByteSlice = rs.bytesClone(whole); - const _83: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 455, col: 60 }); + const _83: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 482, col: 60 }); const _79: rs.ByteSlice = rs.bytesSplitTo(rs.place(() => _81, (value9) => _81 = value9), _83); rs.byteVecExtendFromSlice(out, _79); rs.bytesDrop(_79); rs.bytesDrop(_81); } else if (_52 === 6) { let _89: rs.ByteSlice = rs.bytesClone(whole); - const _91: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 456, col: 61 }); + const _91: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 483, col: 61 }); const _87: rs.ByteSlice = rs.bytesSplitOff(rs.place(() => _89, (value8) => _89 = value8), _91); rs.byteVecExtendFromSlice(out, _87); rs.bytesDrop(_87); rs.bytesDrop(_89); } else if (_52 === 7) { let _94: rs.ByteSlice = rs.bytesClone(whole); - const _96: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 457, col: 36 }); + const _96: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 484, col: 36 }); rs.bytesAdvance(rs.place(() => _94, (value7) => _94 = value7), _96); rs.bytesDrop(_94); } else if (_52 === 8) { @@ -713,12 +721,12 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.bytesDrop(_101); } else if (_52 === 9) { let _107: rs.ByteSlice = rs.bytesClone(whole); - const _109: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 459, col: 50 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 459, col: 46 }); + const _109: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 486, col: 50 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 486, col: 46 }); rs.byteVecPush(out, rs.u64Low(rs.u64FromBeBytes(rs.bytesReadInt(rs.place(() => _107, (value5) => _107 = value5), 8, _109, false, false))) & 0xff); rs.bytesDrop(_107); } else if (_52 === 10) { - let _114: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 460, col: 21 }); - const _116: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 460, col: 35 }); + let _114: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 487, col: 21 }); + const _116: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 487, col: 35 }); rs.byteSliceAdvance(rs.place(() => _114, (value4) => _114 = value4), _116); } else if (_52 === 11) { let _120: rs.ByteSlice = rs.bytesClone(whole); @@ -727,75 +735,75 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.bytesDrop(_120); } else if (_52 === 12) { let _129: rs.ByteSlice = rs.bytesClone(whole); - const _131: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 462, col: 66 }); + const _131: rs.usize = rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 489, col: 66 }); const _127: rs.ByteSlice = rs.bytesSplitTo(rs.place(() => _129, (value2) => _129 = value2), _131); rs.byteVecExtendFromSlice(out, _127); rs.bytesDrop(_127); rs.bytesDrop(_129); } else if (_52 === 13) { - let _137: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 44 }); - const _139: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 463, col: 64 }); + let _137: rs.ByteSlice = rs.byteSliceRange(data, 0, undefined, { file: "fixtures/lang/panics/src/hooked.rs", line: 490, col: 44 }); + const _139: rs.usize = rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 490, col: 64 }); const _135: rs.ByteSlice = rs.byteSliceCopyToBytes(rs.place(() => _137, (value) => _137 = value), _139); rs.byteVecExtendFromSlice(out, _135); rs.bytesDrop(_135); } else if (_52 === 14) { const _146: rs.BytesMut = rs.bytesMutFrom(data); - const _144: rs.BytesMut = rs.bytesMutSplitTo(_146, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 464, col: 68 })); + const _144: rs.BytesMut = rs.bytesMutSplitTo(_146, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 491, col: 68 })); rs.byteVecExtendFromSlice(out, rs.bytesMutView(_144)); _144[Symbol.dispose](); _146[Symbol.dispose](); } else if (_52 === 15) { const _154: rs.BytesMut = rs.bytesMutWithCapacity(4); - const _152: rs.BytesMut = rs.bytesMutSplitOff(_154, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 465, col: 75 })); + const _152: rs.BytesMut = rs.bytesMutSplitOff(_154, rs.usizeAdd(at, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 492, col: 75 })); rs.byteVecExtendFromSlice(out, rs.bytesMutView(_152)); _152[Symbol.dispose](); _154[Symbol.dispose](); } else if (_52 === 16) { - const b: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 467, col: 49 })); - rs.bytesMutSetLen(b, rs.usizeAdd(b.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 469, col: 32 })); + const b: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 494, col: 49 })); + rs.bytesMutSetLen(b, rs.usizeAdd(b.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 496, col: 32 })); rs.byteVecPush(out, b.length & 0xff); b[Symbol.dispose](); } else if (_52 === 17) { - const b2: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 473, col: 49 })); - rs.bytesMutAdvanceMut(b2, rs.usizeAdd(b2.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 475, col: 36 })); + const b2: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 500, col: 49 })); + rs.bytesMutAdvanceMut(b2, rs.usizeAdd(b2.cap, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 502, col: 36 })); rs.byteVecPush(out, b2.length & 0xff); b2[Symbol.dispose](); } else if (_52 === 18) { - const v: rs.ByteVec = rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 479, col: 50 })); - rs.byteVecAdvanceMut(v, rs.usizeAdd(v.data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 481, col: 36 })); + const v: rs.ByteVec = rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 506, col: 50 })); + rs.byteVecAdvanceMut(v, rs.usizeAdd(v.data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 508, col: 36 })); rs.byteVecPush(out, v.length & 0xff); } else if (_52 === 19) { const _197: rs.BytesMut = rs.bytesMutFrom(data); - rs.bytesMutAdvance(_197, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 484, col: 44 })); + rs.bytesMutAdvance(_197, rs.usizeAdd(data.length, 1, { file: "fixtures/lang/panics/src/hooked.rs", line: 511, col: 44 })); _197[Symbol.dispose](); } else if (_52 === 20) { - const _204: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(data, 0, rs.min(data.length, 3), { file: "fixtures/lang/panics/src/hooked.rs", line: 485, col: 44 })); + const _204: rs.BytesMut = rs.bytesMutFrom(rs.byteSliceRange(data, 0, rs.min(data.length, 3), { file: "fixtures/lang/panics/src/hooked.rs", line: 512, col: 44 })); rs.byteVecPush(out, (rs.bytesMutReadWord(_204, 4, false) as rs.u32) & 0xff); _204[Symbol.dispose](); } else if (_52 === 21) { - const _212: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 486, col: 48 })); + const _212: rs.BytesMut = rs.bytesMutWithCapacity(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 513, col: 48 })); rs.byteVecPush(out, _212.cap & 0xff); _212[Symbol.dispose](); } else if (_52 === 22) { const _tail: rs.BytesMut = rs.bytesMutSplitOff(shared, 4); - rs.bytesMutReserve(shared, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 490, col: 41 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 490, col: 28 })); + rs.bytesMutReserve(shared, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 517, col: 41 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 517, col: 28 })); _tail[Symbol.dispose](); } else if (_52 === 23) { rs.bytesMutSplitTo(shared, 4)[Symbol.dispose](); - rs.bytesMutReserve(shared, rs.usizeSub(4294967295 - 4, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 495, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 495, col: 28 })); + rs.bytesMutReserve(shared, rs.usizeSub(4294967295 - 4, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 522, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 522, col: 28 })); } else if (_52 === 24) { const _235: rs.u64 = n as rs.u64; - const _236: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 497, col: 49 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 497, col: 45 }); + const _236: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 524, col: 49 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 524, col: 45 }); rs.bytesMutPutInt(shared, rs.u64ToBeBytes(_235), _236, false); } else if (_52 === 25) { const _240: rs.i64 = n as rs.i64; - const _241: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 498, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 498, col: 41 }); + const _241: rs.usize = rs.usizeAdd(9, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 525, col: 45 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 525, col: 41 }); rs.byteVecPutInt(out, rs.i64ToBeBytes(_240), _241, false); } else if (_52 === 26) { - rs.byteVecPutFill(out, n, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 499, col: 53 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 499, col: 40 })); + rs.byteVecPutFill(out, n, rs.usizeSub(4294967295, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 526, col: 53 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 526, col: 40 })); } else if (_52 === 27) { const _253: Take.Take = buf_impl_take$bytes_Buf_bytes_Bytes(rs.bytesClone(whole), 2); - const _251: rs.ByteSlice = Take.copyToBytes$bytes_Buf_bytes_Bytes(_253, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 500, col: 74 })); + const _251: rs.ByteSlice = Take.copyToBytes$bytes_Buf_bytes_Bytes(_253, rs.usizeAdd(at, 3, { file: "fixtures/lang/panics/src/hooked.rs", line: 527, col: 74 })); rs.byteVecExtendFromSlice(out, _251); rs.bytesDrop(_251); drop$bytes_buf_Take_bytes_Bytes(_253); @@ -805,15 +813,15 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { drop$bytes_buf_Take_bytes_Bytes(_261); } else if (_52 === 29) { const chunk: rs.ByteSlice = rs.bytesMutChunkMut(shared); - UninitSlice.writeByte(chunk, rs.usizeAdd(UninitSlice.len(chunk), rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 505, col: 44 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 505, col: 30 }), n); + UninitSlice.writeByte(chunk, rs.usizeAdd(UninitSlice.len(chunk), rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 532, col: 44 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 532, col: 30 }), n); } else if (_52 === 30) { - UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(rs.byteVecChunkMut(rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 507, col: 40 }))), new rs.RangeFrom(rs.usizeAdd(65, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 507, col: 65 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 507, col: 60 }), rs.usizeStep), { file: "fixtures/lang/panics/src/hooked.rs", line: 507, col: 59 }), 0, n); + UninitSlice.writeByte(UninitSlice.indexMut$ops_IndexMut_ops_RangeFrom_usize(rs.byteVecChunkMut(rs.byteVecWithCapacity(rs.usizeRem(at, 4, { file: "fixtures/lang/panics/src/hooked.rs", line: 534, col: 40 }))), new rs.RangeFrom(rs.usizeAdd(65, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 534, col: 65 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 534, col: 60 }), rs.usizeStep), { file: "fixtures/lang/panics/src/hooked.rs", line: 534, col: 59 }), 0, n); } else if (_52 === 31) { const _287: rs.BytesMut = rs.bytesMutWithCapacity(0); - UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(rs.bytesMutChunkMut(_287), { end: rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 508, col: 45 }) }, { file: "fixtures/lang/panics/src/hooked.rs", line: 508, col: 42 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); + UninitSlice.copyFromSlice(UninitSlice.indexMut$ops_IndexMut_ops_RangeTo_usize(rs.bytesMutChunkMut(_287), { end: rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 535, col: 45 }) }, { file: "fixtures/lang/panics/src/hooked.rs", line: 535, col: 42 }), rs.byteSliceFrom(rs.bytes(3).fill(n))); _287[Symbol.dispose](); } else { - const _297: rs.BytesMut = rs.bytesMutZeroed(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 509, col: 40 })); + const _297: rs.BytesMut = rs.bytesMutZeroed(rs.usizeSub(4294967295, at, { file: "fixtures/lang/panics/src/hooked.rs", line: 536, col: 40 })); rs.byteVecPush(out, _297.length & 0xff); _297[Symbol.dispose](); } @@ -829,7 +837,7 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { */ export function edition2018Panicked(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { b0: { - if (!(rs.u8Rem(kind, 7, { file: "fixtures/lang/panics/src/hooked.rs", line: 517, col: 8 }) !== 6)) { + if (!(rs.u8Rem(kind, 7, { file: "fixtures/lang/panics/src/hooked.rs", line: 544, col: 8 }) !== 6)) { if (!(option_unwrapOr$1fr498u(rs.byteSliceFirst(data), 0) > 200)) { break b0; } @@ -839,4 +847,29 @@ export function edition2018Panicked(kind: rs.u8, data: rs.ByteSlice, out: rs.Byt edition2018_panicked(kind, data, out); } +/** + * A panic of tokio's own code in what translation maps, with a hook set: a oneshot + * receiver polled again once it gave its value. + */ +export function tokioStock(_kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { + const n: rs.u8 = option_unwrapOr$1fr498u(rs.byteSliceFirst(data), 0); + hook(); + const _10: [rs.OneshotSender, rs.OneshotReceiver] = rs.oneshotChannel(); + const tx: rs.OneshotSender = _10[0]; + const rx: rs.OneshotReceiver = _10[1]; + rs.resultUnwrap(rs.oneshotSend(tx, n), rs.u8Debug, { file: "fixtures/lang/panics/src/hooked.rs", line: 556, col: 16 }); + const cx: rs.Context = rs.NOOP_WAKER; + let iterStart: rs.i32 = 0; + const iterEnd: rs.i32 = 2; + while (iterStart++ < iterEnd) { + const _21: rs.Poll> = rs.oneshotPoll(rx, cx, { _0: undefined }); + if (_21 !== rs.Pending) { + if (_21.ok) { + rs.byteVecPush(out, _21.value); + } + } + } + rx[Symbol.dispose](); +} + //# sourceMappingURL=hooked.ts.map diff --git a/ts/fixtures/lang/panics/hook/expected/lib.ts b/ts/fixtures/lang/panics/hook/expected/lib.ts index e8d9f0201..be1a7e2f0 100644 --- a/ts/fixtures/lang/panics/hook/expected/lib.ts +++ b/ts/fixtures/lang/panics/hook/expected/lib.ts @@ -4,7 +4,7 @@ import * as rs from "./rs.ts"; import type * as Take from "./bytes/buf/take.Take.ts"; import type * as Any from "./core/any.Any.ts"; import { panicked as edition2018_panicked } from "./edition2018.ts"; -import { panicked as hooked_panicked, aborted, sited, stock, edition2018Panicked } from "./hooked.ts"; +import { panicked as hooked_panicked, aborted, sited, stock, edition2018Panicked, tokioStock } from "./hooked.ts"; import { via$located_Tracked_u8, at$located_Tracked_u8, called as located_called, read, panicked as located_panicked } from "./located.ts"; import * as Inherits from "./located.Inherits.ts"; import * as Own from "./located.Own.ts"; @@ -158,7 +158,7 @@ export class ofPlace$u8 { * their count, so a case added at the end moves no other. */ export function cases(): rs.Vec<[string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]> { - return rs.iterToVec(rs.iterChain(rs.vecIntoIter(rs.vecFrom([["panics::wrapped", wrapped as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::called", panics_called as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::awaited", awaited as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::raised", raised as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::called", located_called as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::read", read as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::panicked", located_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["edition2018::panicked", edition2018_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]])), rs.iterSlice([["hooked::panicked", hooked_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::aborted", aborted as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::sited", sited as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::stock", stock as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::edition2018_panicked", edition2018Panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]])), undefined, 12, true); + return rs.iterToVec(rs.iterChain(rs.vecIntoIter(rs.vecFrom([["panics::wrapped", wrapped as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::called", panics_called as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::awaited", awaited as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["panics::raised", raised as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::called", located_called as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::read", read as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["located::panicked", located_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["edition2018::panicked", edition2018_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]])), rs.iterSlice([["hooked::panicked", hooked_panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::aborted", aborted as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::sited", sited as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::stock", stock as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::edition2018_panicked", edition2018Panicked as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined], ["hooked::tokio_stock", tokioStock as (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined] as [string, (a0: rs.u8, a1: rs.ByteSlice, a2: rs.ByteVec) => undefined]])), undefined, 12, true); } export const NOTE: rs.LocalKey> = /* @__PURE__ */ new rs.LocalKey(NOTE$init, false); @@ -171,7 +171,7 @@ export function NOTE$init(): rs.RefCell { export function note(): rs.String { return rs.localKeyWithBorrowMut(NOTE, (a0: rs.String): rs.String => { return rs.replaceIn(a0, rs.stringNew()); - }, { file: "fixtures/lang/panics/src/lib.rs", line: 55, col: 5 }); + }, { file: "fixtures/lang/panics/src/lib.rs", line: 56, col: 5 }); } //# sourceMappingURL=lib.ts.map diff --git a/ts/fixtures/lang/panics/hook/expected/tokio/sync/oneshot/error.RecvError.ts b/ts/fixtures/lang/panics/hook/expected/tokio/sync/oneshot/error.RecvError.ts new file mode 100644 index 000000000..08add3b0c --- /dev/null +++ b/ts/fixtures/lang/panics/hook/expected/tokio/sync/oneshot/error.RecvError.ts @@ -0,0 +1,12 @@ +// Generated by rust2-ts. Do not edit. + +/** + * Error returned by the `Future` implementation for `Receiver`. + * + * This error is returned by the receiver when the sender is dropped without sending. + */ +export interface RecvError { + _0: undefined; +} + +//# sourceMappingURL=error.RecvError.ts.map diff --git a/ts/fixtures/lang/panics/src/hooked.rs b/ts/fixtures/lang/panics/src/hooked.rs index bed712bb9..ddc1b29f3 100644 --- a/ts/fixtures/lang/panics/src/hooked.rs +++ b/ts/fixtures/lang/panics/src/hooked.rs @@ -195,7 +195,7 @@ pub fn sited(kind: u8, data: &[u8], out: &mut Vec) { let deque = VecDeque::from(v.clone()); let map = BTreeMap::from([(u16::from(n), n)]); let set = BTreeSet::from([u16::from(n)]); - match kind % 86 { + match kind % 87 { 0 => out.push(Vec::::with_capacity(usize::MAX - at).len() as u8), 1 => v.clone().rotate_right(at + 3), 2 => out.push(n.clamp(n.max(1), n.max(1) - 1)), @@ -352,7 +352,8 @@ pub fn sited(kind: u8, data: &[u8], out: &mut Vec) { 82 => out.push((-i32::from(n)).clamp(0, -1) as u8), 83 => out.extend_from_slice(format!("{Failing}").as_bytes()), 84 => out.extend_from_slice(Failing.to_string().as_bytes()), - _ => out.push(Lying(n).len() as u8), + 85 => out.push(Lying(n).len() as u8), + _ => out.extend(Short(n % 4).zip(0..n % 4 + 1).rev().map(|(a, b)| a ^ b)), } } @@ -423,6 +424,32 @@ impl Iterator for Lying { impl ExactSizeIterator for Lying {} +/// An iterator of one item fewer than the length it says, which a zip from the back finds +/// short. +struct Short(u8); + +impl Iterator for Short { + type Item = u8; + + fn next(&mut self) -> Option { + self.next_back() + } + + fn size_hint(&self) -> (usize, Option) { + let len = usize::from(self.0) + 1; + (len, Some(len)) + } +} + +impl DoubleEndedIterator for Short { + fn next_back(&mut self) -> Option { + self.0 = self.0.checked_sub(1)?; + Some(self.0) + } +} + +impl ExactSizeIterator for Short {} + /// One panic of `bytes`' own code, by `kind`, with a hook set: each where the native build /// names it, in the source of the `bytes` it builds. pub fn stock(kind: u8, data: &[u8], out: &mut Vec) { @@ -519,3 +546,18 @@ pub fn edition2018_panicked(kind: u8, data: &[u8], out: &mut Vec) { } edition2018::panicked(kind, data, out); } + +/// A panic of tokio's own code in what translation maps, with a hook set: a oneshot +/// receiver polled again once it gave its value. +pub fn tokio_stock(_kind: u8, data: &[u8], out: &mut Vec) { + let n = data.first().copied().unwrap_or(0); + hook(); + let (tx, mut rx) = tokio::sync::oneshot::channel(); + tx.send(n).unwrap(); + let mut cx = Context::from_waker(Waker::noop()); + for _ in 0..2 { + if let Poll::Ready(Ok(n)) = Pin::new(&mut rx).poll(&mut cx) { + out.push(n); + } + } +} diff --git a/ts/fixtures/lang/panics/src/lib.rs b/ts/fixtures/lang/panics/src/lib.rs index 7d346af88..7deb5b7e9 100644 --- a/ts/fixtures/lang/panics/src/lib.rs +++ b/ts/fixtures/lang/panics/src/lib.rs @@ -40,6 +40,7 @@ fn cases() -> Vec<(&'static str, Case)> { ("hooked::sited", hooked::sited), ("hooked::stock", hooked::stock), ("hooked::edition2018_panicked", hooked::edition2018_panicked), + ("hooked::tokio_stock", hooked::tokio_stock), ]) .collect(); cases diff --git a/ts/runtime/rs.ts b/ts/runtime/rs.ts index 6f937c40c..3a19c603e 100644 --- a/ts/runtime/rs.ts +++ b/ts/runtime/rs.ts @@ -67,12 +67,24 @@ export function panic(message: string, at?: Location | string, owned?: boolean | * nothing past it: a panic that can't unwind, at `at` or at the key of std's site. */ export function precondition(value: T | undefined, check: string, at?: Location | string): T { - if (value === undefined) { - panic(`unsafe precondition(s) violated: ${check}\n\nThis indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.`, at); - } + if (value === undefined) panic(violation(check), at); return value; } +/** The message of std's debug check that an unsafe function's precondition `check` held. */ +function violation(check: string): string { + return `unsafe precondition(s) violated: ${check}\n\nThis indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.`; +} + +/** + * Abort where the program broke `check`, which Rust leaves undefined, worded as std's + * debug checks of an unsafe function's preconditions are. Nothing native does there is + * defined, so no hook runs. + */ +export function violated(check: string): never { + throw new Abort(violation(check)); +} + /** * Panic at `at` with `message`: literal pieces, and the `usize`s between them, which a * hook reads as the `String` std's `panic!` writes each piece and number into. @@ -299,7 +311,7 @@ class TextAt extends AtIndex { } override set v(_: number) { - throw textWrite(); + textWrite(); } override at(index: number): TextAt { @@ -307,9 +319,9 @@ class TextAt extends AtIndex { } } -/** The failure of a write, or a mutable slice, through a `TextAt`. */ -function textWrite(): Error { - return new Error("rust2-ts: a write through a pointer into a `str`'s bytes, which Rust forbids"); +/** A write, or a mutable slice, through a `TextAt`, which a shared reference made. */ +function textWrite(): never { + return violated("a write requires a pointer not made from a shared reference, as `str::as_ptr`'s is"); } /** `str::as_ptr`: the read-only pointer to the first byte of its UTF-8. */ @@ -363,10 +375,14 @@ function addressAt(addr: number): Address { return at; } -function nowhere(): never { - throw new Error("rust2-ts: a read or write through a pointer to no memory"); +/** A read or write through a pointer to no memory. */ +export function nowhere(): never { + return violated("a read or write requires a pointer to memory, not null, dangling, or moved off either"); } +/** What null and dangling pointers point into: no elements, which any access through them is past. */ +export const NO_MEMORY: readonly never[] = /* @__PURE__ */ Object.freeze([]); + /** The array of one element that a pointer to a value in no array points into, by its place. */ const LONE = /* @__PURE__ */ new WeakMap, unknown[]>(); @@ -423,7 +439,7 @@ function elemOf(p: Place): AtIndex { const view = (p.array as { [VIEW]?: View })[VIEW]; return view ? new AtIndex(view.s, view.start + p.index) : p; } - if (p === NULL || p === DANGLING) return new AtIndex([] as T[], 0); + if (p === NULL || p === DANGLING) return new AtIndex(NO_MEMORY as unknown as T[], 0); let lone = LONE.get(p) as T[] | undefined; if (!lone) { lone = new Proxy(new Array(1), new Lone(p)); @@ -487,7 +503,7 @@ export function ptrOffsetFrom(p: Place, origin: Place): number { export function ptrCopy(src: Place, dst: Place, n: number, copy?: (value: T) => T): void { if (n === 0) return; const [from, to] = [elemOf(src), elemOf(dst)]; - if (to instanceof TextAt) throw textWrite(); + if (to instanceof TextAt) textWrite(); from.reach(n); to.reach(n); if (ArrayBuffer.isView(from.array) && ArrayBuffer.isView(to.array)) { @@ -663,7 +679,7 @@ export function ptrByteSlice(p: Place, len: number, shared: boolean): By } const at = elemOf(p); at.reach(len); - if (!shared && len !== 0 && at instanceof TextAt) throw textWrite(); + if (!shared && len !== 0 && at instanceof TextAt) textWrite(); if (at.array instanceof Uint8Array) return new ByteSlice(at.array, at.index, len); // A byte in no array, which no `Uint8Array` can share. if (!shared) throw new Error("rust2-ts: a raw or mutable slice of a byte in no array of bytes"); diff --git a/ts/runtime/rs/alloc.ts b/ts/runtime/rs/alloc.ts index a628ffcd3..297fd904f 100644 --- a/ts/runtime/rs/alloc.ts +++ b/ts/runtime/rs/alloc.ts @@ -5,7 +5,7 @@ // write of its bytes fails. `realloc` keeps the values in a new array, and `dealloc` lets // the array go; a pointer into it after either reads what Rust leaves undefined. -import { Abort, Err, type Fmt, type FmtResult, type Formatter, fmtDebugStructFields, fmtPad, fmtWriteFmt, Ok, type Place, type Result } from "../rs.ts"; +import { Abort, Err, type Fmt, type FmtResult, type Formatter, fmtDebugStructFields, fmtPad, fmtWriteFmt, Ok, type Place, type Result, violated } from "../rs.ts"; import { AtIndex } from "./collections.ts"; import { type u32, u32Debug, type usize, usizeDebug } from "./int.ts"; @@ -184,7 +184,7 @@ export function allocBytes(p: Place, elem: number, type: string): Block /** The block the pointer `p` to bytes, which `dealloc` or `realloc` takes, is. */ function blockOf(p: Place): Block { - if (!(p instanceof Block)) throw new Error("rust2-ts: memory freed or grown that isn't from `alloc`"); + if (!(p instanceof Block)) violated("dealloc and realloc require memory that alloc gave"); return p; } diff --git a/ts/runtime/rs/collections.ts b/ts/runtime/rs/collections.ts index f2568c160..63bc470d8 100644 --- a/ts/runtime/rs/collections.ts +++ b/ts/runtime/rs/collections.ts @@ -15,7 +15,7 @@ // A function that may drop a key, value, or item std's would, rather than return or keep // it, takes what drops each that does, as `k`, `v`, or `f`, and drops it where std's does. -import { type ArrayRef, ArraySlice, arraySliceOfSlice, Borrowed, ByteSlice, ByteVec, byteVecPush, byteVecReserve, capReserve, capReserveExact, capTryReserve, capTryReserveExact, type CloneFrom, type Debug, debugStructField, debugStructFinishNonExhaustive, Err, type Fmt, fmtDebugStruct, fmtDebugStructFields, fmtDebugTupleFields, fmtIter, fmtList, type FmtResult, fmtSet, fmtTuple, type Formatter, type None, OK, Ok, panic, type Place, type RangeBound, rangeCheck, type Result, type Room, roomPast, searchBy, type Elements, Slice, sliceData, sliceFrom, sliceLength, sliceSort, sliceStart, Vec, vecAppend, vecCapacity, vecCloneFrom, vecFrom, vecHold, vecKeep, vecMax, vecReserve, vecWithCapacity, panicSizes } from "../rs.ts"; +import { type ArrayRef, ArraySlice, NO_MEMORY, nowhere, arraySliceOfSlice, Borrowed, ByteSlice, ByteVec, byteVecPush, byteVecReserve, capReserve, capReserveExact, capTryReserve, capTryReserveExact, type CloneFrom, type Debug, debugStructField, debugStructFinishNonExhaustive, Err, type Fmt, fmtDebugStruct, fmtDebugStructFields, fmtDebugTupleFields, fmtIter, fmtList, type FmtResult, fmtSet, fmtTuple, type Formatter, type None, OK, Ok, panic, type Place, type RangeBound, rangeCheck, type Result, type Room, roomPast, searchBy, type Elements, Slice, sliceData, sliceFrom, sliceLength, sliceSort, sliceStart, Vec, vecAppend, vecCapacity, vecCloneFrom, vecFrom, vecHold, vecKeep, vecMax, vecReserve, vecWithCapacity, panicSizes } from "../rs.ts"; import { allocError, CAPACITY_OVERFLOW, type TryReserveError } from "./alloc.ts"; import type { HashKey, Hashing } from "./hash.ts"; import { type Limbs, lt, type u64, type usize } from "./int.ts"; @@ -438,6 +438,7 @@ export class AtIndex implements Place { /** The room past the array that holds `n` elements from here, which `reach` requires. */ private room(n: number): Room { const room = this.index >= 0 ? roomPast(this.array, this.index + n) : undefined; + if (room === undefined && this.array === NO_MEMORY) nowhere(); if (room === undefined) throw new Error("rust2-ts: a read or write through a pointer past the array JS keeps it in"); return room; } diff --git a/ts/runtime/rs/iter.ts b/ts/runtime/rs/iter.ts index c2895d7d5..96a6ae3be 100644 --- a/ts/runtime/rs/iter.ts +++ b/ts/runtime/rs/iter.ts @@ -22,7 +22,7 @@ // `owned` functions follow it, dispatching on the kind, so a bundle that never drops an // item carries none of it. -import { ByteSlice, ByteVec, type ArrayRef, type ArraySlice, arraySliceItems, arraySliceAt, arraySlicePart, byteVecExtendFromSlice, byteVecPush, byteVecReserve, byteVecReserveExact, byteVecShrinkTo, byteVecWithCapacity, capReserve, type Debug, Err, type Fmt, type FmtResult, type Formatter, fmtBool, fmtDebugStructFields, fmtDebugTupleFields, fmtOption, type None, Ok, type Place, panic, place, type RangeBound, type Result, sliceItems, slicePart, type Slice, type SliceLike, Vec, vecCapacity, vecExtendFromSlice, vecFrom, vecHold, vecMax, vecWithCapacity, assertFailed, fmtOwned } from "../rs.ts"; +import { ByteSlice, ByteVec, violated, type ArrayRef, type ArraySlice, arraySliceItems, arraySliceAt, arraySlicePart, byteVecExtendFromSlice, byteVecPush, byteVecReserve, byteVecReserveExact, byteVecShrinkTo, byteVecWithCapacity, capReserve, type Debug, Err, type Fmt, type FmtResult, type Formatter, fmtBool, fmtDebugStructFields, fmtDebugTupleFields, fmtOption, type None, Ok, type Place, panic, place, type RangeBound, type Result, sliceItems, slicePart, type Slice, type SliceLike, Vec, vecCapacity, vecExtendFromSlice, vecFrom, vecHold, vecMax, vecWithCapacity, assertFailed, fmtOwned } from "../rs.ts"; import { AtIndex, BTreeIter, HashIter, type Ordering } from "./collections.ts"; import { type Hasher, hash8 } from "./hash.ts"; import { charStep, intToBig, type Limbs, type Step, usizeDebug, lt as wideLt } from "./int.ts"; @@ -3417,7 +3417,7 @@ class ZipIter extends Iter<[A, B]> implements Disposable { const a = this.a.nextBack(); const b = this.b.nextBack(); if (a === DONE && b === DONE) return DONE; - if (a === DONE || b === DONE) panic("internal error: entered unreachable code"); + if (a === DONE || b === DONE) panic("internal error: entered unreachable code", "zip_next_back"); return [a, b]; } @@ -3466,7 +3466,8 @@ class ZipFold extends Iter<[A, B]> { this.left--; const a = this.a.next(); const b = this.b.next(); - if (a === DONE || b === DONE) panic("internal error: entered unreachable code"); + // Only std's iterators are `TrustedLen`, which never run out early. + if (a === DONE || b === DONE) violated("hint::unreachable_unchecked must never be reached"); return [a, b]; } diff --git a/ts/runtime/rs/task.ts b/ts/runtime/rs/task.ts index 019616f4e..0d488e7ef 100644 --- a/ts/runtime/rs/task.ts +++ b/ts/runtime/rs/task.ts @@ -4,7 +4,7 @@ // A value whose drop JS can observe has `[Symbol.dispose]`, which runs its `Drop` impl // and drops its fields. `None` is `undefined`, which drops as nothing. -import { Abort, arrayAssign, type ByteSlice, type ArrayRef, type LentArray, type ElemCopy, ArraySlice, arraySliceItems, arraySliceCopy, arraySliceSet, type CloneFrom, cloneOver, type Debug, type DebugStruct, debugStructField, debugStructFinish, debugStructFinishNonExhaustive, debugTupleField, debugTupleFinish, Err, type FmtResult, type Formatter, fmtBool, fmtDebugStruct, fmtDebugTuple, fmtDebugTupleFields, fmtPad, fmtStr, type None, NULL, objectCopy, OK, Ok, Panic, panic, type Place, place, ptrErase, ptrHome, ptrNowhere, ptrWrite, type Result, Slice, stringAsBytes, type Vec, assertFailed, fmtOwned } from "../rs.ts"; +import { Abort, arrayAssign, type ByteSlice, type ArrayRef, type LentArray, type ElemCopy, ArraySlice, arraySliceItems, arraySliceCopy, arraySliceSet, type CloneFrom, cloneOver, type Debug, type DebugStruct, debugStructField, debugStructFinish, debugStructFinishNonExhaustive, debugTupleField, debugTupleFinish, Err, type FmtResult, type Formatter, fmtBool, fmtDebugStruct, fmtDebugTuple, fmtDebugTupleFields, fmtPad, fmtStr, type None, NULL, objectCopy, OK, Ok, Panic, panic, type Place, place, ptrErase, ptrHome, ptrNowhere, ptrWrite, type Result, Slice, violated, stringAsBytes, type Vec, assertFailed, fmtOwned } from "../rs.ts"; import type { Hasher } from "./hash.ts"; import type { Location } from "./location.ts"; @@ -336,13 +336,13 @@ export function arcRaw

(arc: Arc, p: P, of: "Arc" | "R /** * `Arc::from_raw`, of an `Arc` or an `Rc` as `of` says: the one `p` points into, which * `into_raw` or `as_ptr` gave, or arithmetic moved back to, and a count of which it takes, - * as std's does. Any other pointer, or one to a value already dropped, fails, as JS keeps - * no count beside it. + * as std's does. Any other pointer, or one to a value already dropped, which Rust leaves + * undefined, aborts. */ export function arcFromRaw(p: object, of: "Arc" | "Rc"): Arc { const arc = (of === "Arc" ? RAW_ARCS : RAW_RCS).get(ptrHome(p)); - if (arc === undefined) throw new Error(`rust2-ts: \`${of}::from_raw\` of a pointer no \`${of}::into_raw\` or \`as_ptr\` gave`); - if (arc.strong === 0) throw new Error(`rust2-ts: \`${of}::from_raw\` of a pointer to a value already dropped`); + if (arc === undefined) violated(`${of}::from_raw requires a pointer that ${of}::into_raw or ${of}::as_ptr gave`); + if (arc.strong === 0) violated(`${of}::from_raw requires a pointer to a value not yet dropped`); return arc as Arc; } diff --git a/ts/runtime/rs/tokio.ts b/ts/runtime/rs/tokio.ts index c39f019fb..0ff5f7792 100644 --- a/ts/runtime/rs/tokio.ts +++ b/ts/runtime/rs/tokio.ts @@ -1609,7 +1609,7 @@ export function oneshotTryRecv(rx: OneshotReceiver, empty: E, closed: E /** A receiver's `Future::poll`: `Ok` of the value, or `error` once the sender dropped without one. */ export function oneshotPoll(rx: OneshotReceiver, cx: Context, error: E): Poll> { const inner = rx.inner; - if (inner === undefined) panic("called after complete"); + if (inner === undefined) panic("called after complete", "tokio_oneshot_poll"); const value = inner.pollRecv(cx); if (value === Pending) return Pending; oneshotFinish(rx); diff --git a/ts/src/lower/caller.rs b/ts/src/lower/caller.rs index dad6dba08..a5f1f9f1b 100644 --- a/ts/src/lower/caller.rs +++ b/ts/src/lower/caller.rs @@ -9,9 +9,9 @@ //! A program that reaches `panic::set_hook` passes where each panic is, which its hook //! reads: each statement's own, the caller's location to each std function that takes it, //! and the call of the macro that defines one, as an integer's methods. A panic in std's -//! own code is where the toolchain's source has it, and one in `bytes`' where the -//! program's `bytes` has it, named as the session names that file, which `rs.setHook` is -//! given. +//! own code is where the toolchain's source has it, and one in `bytes`' or `tokio`'s where +//! the program's copy of that crate has it, named as the session names that file, which +//! `rs.setHook` is given. use std::sync::OnceLock; @@ -327,6 +327,14 @@ const SITES: &[(&str, &str, &str, &str)] = &[ "", "expect(\"multiplying duration by scalar", ), + // A macro's panic is at the macro's call, here the one that gives the general zip its + // `next_back`, which an `ExactSizeIterator` whose length lies reaches. + ( + "zip_next_back", + "core/src/iter/adapters/zip.rs", + "// General Zip impl", + "zip_impl_general_defaults!", + ), ]; /// Where each std function that neither takes its caller's location nor is defined by a @@ -469,11 +477,14 @@ const CALLEES: &[(&str, &str, &str, &str)] = &[ ), ]; -/// Where `bytes`' code panics, for each of its panics the runtime makes, by the key it +/// Where a crate's code panics, for each of its panics the runtime makes, by the key it /// passes in place of a location: a file under the crate's `src/`, the texts before it in -/// turn, and the text the call that panics starts with. None of its public functions takes -/// its caller's location, so each panic is where its source has it. -const BYTES: &[(&str, &str, &[&str], &str)] = &[ +/// turn, and the text the call that panics starts with. +type CrateSites = &'static [(&'static str, &'static str, &'static [&'static str], &'static str)]; + +/// Where `bytes`' code panics. None of its public functions takes its caller's location, so +/// each panic is where its source has it. +const BYTES: CrateSites = &[ ("bytes_advance", "lib.rs", &["fn panic_advance("], "panic!("), ("bytes_does_not_fit", "lib.rs", &["fn panic_does_not_fit("], "panic!("), // `range` takes its caller's location, so its panics are at its call. @@ -526,9 +537,18 @@ const BYTES: &[(&str, &str, &[&str], &str)] = &[ ), ]; +/// Where tokio's code panics in what its mapping covers, none of which takes its caller's +/// location. +const TOKIO: CrateSites = &[( + "tokio_oneshot_poll", + "sync/oneshot.rs", + &["impl Future for Receiver", "fn poll("], + "panic!(", +)]; + /// The `rs.Sites` of the toolchain's std, which `rs.setHook` takes: where each panic -/// [`SITES`] names is, as the native build names it, and each [`BYTES`] names, in the -/// program's `bytes`, if it has one. +/// [`SITES`] names is, as the native build names it, and each [`BYTES`] and [`TOKIO`] name, +/// in the program's `bytes` and `tokio`, if it has them. pub fn sites(t: &mut Translator<'_, '_>, span: Span) -> Expr { let tcx = t.tcx; let mut props = Vec::new(); @@ -543,30 +563,31 @@ pub fn sites(t: &mut Translator<'_, '_>, span: Span) -> Expr { } } } - props.extend(bytes_sites(t, span)); + props.extend(crate_sites(t, span, "bytes", BYTES)); + props.extend(crate_sites(t, span, "tokio", TOKIO)); Expr::Object(props) } -/// The sites [`BYTES`] names, in the program's `bytes`: none without one, and an error for -/// versions whose sites differ, as the runtime's panics are one crate's. -fn bytes_sites(t: &mut Translator<'_, '_>, span: Span) -> Vec<(Key, Expr)> { +/// The sites `table` names, in the program's crate `name`: none without one, and an error +/// for versions whose sites differ, as the runtime's panics are one crate's. +fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateSites) -> Vec<(Key, Expr)> { let tcx = t.tcx; let mut tables: Vec> = Vec::new(); for &krate in tcx.crates(()) { - if tcx.crate_name(krate).as_str() != "bytes" { + if tcx.crate_name(krate).as_str() != name { continue; } tcx.import_source_files(krate); let mut props = Vec::new(); - for &(key, file, after, needle) in BYTES { - match bytes_find(tcx, krate, file, after, needle) { + for &(key, file, after, needle) in table { + match crate_find(tcx, krate, file, after, needle) { Some(at) => props.push((Key::Name(key.into()), at)), None => { let after = after.join(" then "); t.err( span, format!( - "the bytes crate's source has no `{needle}` in `src/{file}` after `{after}`, where it panics" + "the {name} crate's source has no `{needle}` in `src/{file}` after `{after}`, where it panics" ), ); } @@ -579,7 +600,9 @@ fn bytes_sites(t: &mut Translator<'_, '_>, span: Span) -> Vec<(Key, Expr)> { if tables.len() > 1 { t.err( span, - "a panic hook in a program of two versions of the bytes crate, whose panics are at different places", + format!( + "a panic hook in a program of two versions of the {name} crate, whose panics are at different places" + ), ); } tables.pop().unwrap_or_default() @@ -587,7 +610,7 @@ fn bytes_sites(t: &mut Translator<'_, '_>, span: Span) -> Vec<(Key, Expr)> { /// The `rs.Location` of the first `needle` after each of `after` in turn in `file`, under /// `krate`'s `src/`, named as the session names it. -fn bytes_find( +fn crate_find( tcx: TyCtxt<'_>, krate: rustc_span::def_id::CrateNum, file: &str, diff --git a/ts/tests/pointers.ts b/ts/tests/pointers.ts index ce5c4101c..5c627df67 100644 --- a/ts/tests/pointers.ts +++ b/ts/tests/pointers.ts @@ -1,7 +1,8 @@ // A pointer the translation can't follow, such as one a struct's field holds, fails with // a rust2-ts error where JS keeps apart what Rust's reaches, which native Rust can't show: // there each is defined, as `repr(C)` fields are one allocation, and a `Vec`'s capacity -// is past its length. +// is past its length. One Rust leaves undefined, such as a read through a dangling +// pointer, aborts as std's debug checks do. // // usage: node pointers.ts @@ -10,6 +11,8 @@ import { strict as assert } from "node:assert"; import * as rs from "../runtime/rs.ts"; const unsure = (f: () => void) => assert.throws(f, (e: Error) => !(e instanceof rs.Panic) && e.message.startsWith("rust2-ts: ")); +// What Rust leaves undefined aborts, as std's debug checks of unsafe preconditions do. +const undefinedBehavior = (f: () => void) => assert.throws(f, (e: Error) => e instanceof rs.Abort && e.message.startsWith("unsafe precondition(s) violated: ")); // Two `&raw const x` of one variable, each its own `rs.Place`. let x = 5; @@ -77,20 +80,21 @@ unsure(() => rs.allocBytes(words, 4, "f32")); unsure(() => rs.allocBytes(rs.ptrAdd(words, 1), 4, "u32")); // Grown, it keeps its values, as many as fit; freed or grown, a pointer to its values is // no block. -unsure(() => rs.dealloc(words)); -unsure(() => rs.realloc(words, 16)); +undefinedBehavior(() => rs.dealloc(words)); +undefinedBehavior(() => rs.realloc(words, 16)); const grown = rs.realloc(rs.allocBytes(words, 4, "u32"), 18); assert.deepEqual(Array.from(grown.array ?? []), [0xffffffff, undefined, undefined, undefined]); // A dangling pointer read through, written through, or copied from, which Rust leaves // undefined, rather than reading `undefined`. const dangling: rs.Place = rs.DANGLING; -unsure(() => rs.ptrAdd(dangling, 1).v); -unsure(() => { +undefinedBehavior(() => rs.ptrAdd(dangling, 1).v); +undefinedBehavior(() => { rs.ptrAdd(dangling, 1).v = 1; }); -unsure(() => rs.ptrCopy(dangling, rs.arrayAsPtr(vec), 1)); -unsure(() => rs.ptrSlice(dangling, 1)); +undefinedBehavior(() => rs.ptrCopy(dangling, rs.arrayAsPtr(vec), 1)); +undefinedBehavior(() => rs.ptrSlice(dangling, 1)); +undefinedBehavior(() => rs.ptrAdd(rs.NULL as rs.Place, 1).v); assert.equal(vec[0], 7); // A raw slice pointer read through once its `Vec` has shrunk past it, which Rust keeps @@ -129,17 +133,17 @@ assert.notEqual(two, rs.DANGLING_UNIT); const aligned = rs.ptrUnerase(two, "raw::Byte", 1) as object; assert.notEqual(aligned, rs.DANGLING); assert.equal(rs.ptrErase(aligned, "raw::Byte", 1), two); -unsure(() => (aligned as rs.Place).v); +undefinedBehavior(() => (aligned as rs.Place).v); // `Arc::from_raw` of a pointer no `Arc::into_raw` or `as_ptr` gave, such as a box's, of an // `Rc`'s, or of one whose value dropped, which Rust leaves undefined. const task = new rs.Arc({ id: 1 }); const raw = rs.arcRaw(task, task.value, "Arc"); assert.equal(rs.arcFromRaw(raw, "Arc"), task); -unsure(() => rs.arcFromRaw({ id: 1 }, "Arc")); -unsure(() => rs.arcFromRaw(raw, "Rc")); +undefinedBehavior(() => rs.arcFromRaw({ id: 1 }, "Arc")); +undefinedBehavior(() => rs.arcFromRaw(raw, "Rc")); task[Symbol.dispose](); -assert.throws(() => rs.arcFromRaw(raw, "Arc"), /`Arc::from_raw` of a pointer to a value already dropped/); +assert.throws(() => rs.arcFromRaw(raw, "Arc"), /Arc::from_raw requires a pointer to a value not yet dropped/); // Moved off its place by arithmetic and back, which is the same address. const counted = new rs.Arc(7); const at = rs.arcRaw(counted, rs.arcPlace(counted), "Rc"); @@ -159,15 +163,15 @@ const text = rs.strAsPtr("aé"); assert.equal(rs.ptrAdd(text, 2).v, 0xa9); assert.deepEqual(Array.from(rs.byteSliceView(rs.ptrByteSlice(text, 3, true))), [0x61, 0xc3, 0xa9]); assert.equal(rs.ptrOffsetFrom(rs.ptrWrappingAdd(text, 2, 1, 1), text), 2); -unsure(() => { +undefinedBehavior(() => { rs.ptrAdd(text, 1).v = 0; }); -unsure(() => { +undefinedBehavior(() => { rs.ptrWrappingAdd(text, 1, 1, 1).v = 0; }); -unsure(() => rs.ptrCopy(rs.byteSliceAsPtr(rs.byteSliceFrom(Uint8Array.of(1))), rs.ptrAdd(text, 1), 1)); -unsure(() => rs.ptrByteSlice(text, 1, false)); -unsure(() => new rs.RawSlice(text, 3).derefBytes(false)); +undefinedBehavior(() => rs.ptrCopy(rs.byteSliceAsPtr(rs.byteSliceFrom(Uint8Array.of(1))), rs.ptrAdd(text, 1), 1)); +undefinedBehavior(() => rs.ptrByteSlice(text, 1, false)); +undefinedBehavior(() => new rs.RawSlice(text, 3).derefBytes(false)); // None of it is nothing written, and two calls' pointers are two encodings. rs.ptrCopy(rs.byteSliceAsPtr(rs.byteSliceFrom(Uint8Array.of(1))), text, 0); assert.equal(rs.ptrByteSlice(text, 0, false).length, 0); From 6f00fcfb369bb5fea26b23cb9888820845ecba08 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 15:34:57 -0800 Subject: [PATCH 03/10] quest: rewrite ts-runtime-throws to the pointers only run time sees, with the decision they wait on Also keep a mutable slice through str::as_ptr a rust2-ts error, as Stacked Borrows alone makes it undefined, and document the aborts and tokio's sites. Co-Authored-By: Claude Opus 5.5 --- quest/m3/README.md | 2 +- quest/m3/ts-runtime-throws.md | 115 +++++++++++++++++++--------------- ts/README.md | 12 ++-- ts/runtime/rs.ts | 6 +- ts/tests/pointers.ts | 8 +-- 5 files changed, 80 insertions(+), 63 deletions(-) diff --git a/quest/m3/README.md b/quest/m3/README.md index f451cc0fd..438e387b9 100644 --- a/quest/m3/README.md +++ b/quest/m3/README.md @@ -46,7 +46,7 @@ memory model for values whose address is reinterpreted, without a consumer. - [Waiting: drop the lang fixture's mul_add allowance](/quest/m3/ts-fma-allowance.md) - the differential fails on any `mul_add` difference again once wasm32's `fma` rounds exactly - [Waiting: type-check in process with tsrs](/quest/m3/ts-tsrs.md) - rust2-ts checks bindings through tsrs instead of `tsc` once it is a stable library - [Parts of arrays without arrayView](/quest/m3/ts-slice-object.md) - a `&mut [T; N]` to part of an array is taken where it is, with no `Proxy` -- [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - no runtime `rust2-ts:` error where native Rust goes on: an exact slower path, or a refusal at translation +- [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) - no runtime `rust2-ts:` error where native Rust goes on: exact, or refused at translation - [rust2-ts with no ts.toml](/quest/m3/ts-configless.md) - a crate's whole `pub` API translates with no config and no bound items - [Browser APIs through wasm-bindgen](/quest/m3/ts-wasm-bindgen/README.md) - web-sys and js-sys imports become direct JS calls, so idiomatic crates such as web-rs's web-codecs translate as stock crates - [Fields typed by an associated type](/quest/m3/ts-assoc-type-fields.md) - a generic struct's field of `::Item` translates at each instance diff --git a/quest/m3/ts-runtime-throws.md b/quest/m3/ts-runtime-throws.md index f3aa2146c..2eb6e46c5 100644 --- a/quest/m3/ts-runtime-throws.md +++ b/quest/m3/ts-runtime-throws.md @@ -1,70 +1,83 @@ -# [L] Throw only where Rust panics +# [M] Throw only where Rust panics ## Goal Code [rust2-ts](/ts/README.md) generates fails at run time only where the Rust source does: no `rust2-ts:` error the runtime throws where native Rust would go on. Each such -construct translates exactly, through a slower path if it must, or is refused at -translation with a span. Proven by differential tests against native Rust for every -construct that now translates. +construct translates exactly, or is refused at translation with a span. Proven by +differential tests against native Rust for every construct that now translates. ## Plan Decided with the maintainer on 2026-11-04: "we should not panic when Rust would not -panic", and runtime throws that copy Rust's behaviour are fine. +panic", and runtime throws that copy Rust's behaviour are fine. A throw that guards Rust +UB stays, as an abort worded like std's `unsafe precondition(s) violated` check, since +Rust defines nothing there. m3's [unsafe policy](/quest/m3/README.md) (2026-11-07) +supersedes the 2026-11-04 "slower exact path" for `unsafe` gaps: where exactness needs a +new pointer form or pointer metadata, refuse at translation with a span. -- ✅ A slower exact path, no flag: where one exists it is the translation, with the fast - path kept where the translator can prove it applies; refuse at translation only where - none exists. Rejected: refusing with no fallback; an inline opt-in. -- ✅ A throw that guards Rust UB (a read through a null or dangling pointer, `from_raw` of - a value already dropped, freeing memory `alloc` did not give) stays, as an abort worded - like std's `unsafe precondition(s) violated` check, since Rust defines nothing there. +[moq-dev/rust2#661](https://github.com/moq-dev/rust2/pull/661) made the UB guards +`rs.violated` aborts (null, dangling, or moved-off reads and writes, writes through +`str::as_ptr`, `from_raw` of a pointer no `into_raw` gave or of a dropped value, `dealloc` +of memory `alloc` didn't give, a `TrustedLen` zip running out), located std's `Zip` +`unreachable!()` and tokio's oneshot panic in hook programs, and found no other panic a +hook can't locate in a forced-hook survey of the `lang` fixtures. Of `git grep 'rust2-ts: ' +ts/runtime`, these are not gaps: a range's missing `Step` and a fmt width written as a +placeholder (no translation makes either), `rs.u64Of` and its kin given a number past +2^53 (a caller's input), a hook's unlocatable panic (a translator bug guard), and a substring's pointer +read outside its bytes, or a mutable slice through `str::as_ptr` (undefined under Stacked +Borrows; they throw until Rust settles its memory model, decided 2026-11-07 in +[#634](https://github.com/moq-dev/rust2/pull/634)). -The rest are gaps. At `main` they include a panic its hook cannot locate -([#556](https://github.com/moq-dev/rust2/pull/556)), a pointer cast to `()` that is not an -`Arc`'s or `Rc`'s (`rs.arcErase`, [#562](https://github.com/moq-dev/rust2/pull/562), -[#565](https://github.com/moq-dev/rust2/pull/565)), `offset_from` of one Rust allocation -JS keeps in two arrays, a pointer moved past the array JS keeps it in (`AtIndex.reach`, such -as one kept in a field), `Bytes::slice_ref` of other storage, `alloc`'s bytes read as -values, ranges stepped without their type, fmt widths written as a placeholder, a read -through a substring's `str::as_ptr` outside its own bytes but inside its text's -(`s[..1].as_ptr().add(1)`, `s[1..].as_ptr().wrapping_sub(1)`), and a raw or mutable slice -of a byte in a field (a struct's, a tuple's, a closure's capture, or one an async body keeps -across an `.await`), or a cast of one to `*const [u8; N]`: a field's byte has no buffer of -its own, unlike a `u8` local whose `&raw` the body takes, so the fix is a `Uint8Array(1)` -for each `u8` field whose address is taken. A `u8` local whose address only a call takes, -as `ptr::from_mut(&mut b)` does, has none either. -The substring reads are UB under Stacked Borrows and allowed under Tree Borrows, so they -throw until Rust settles its memory model (decided 2026-11-07 in -[#634](https://github.com/moq-dev/rust2/pull/634)); if Rust rules them defined, a -substring's pointer carries its text's encoding and offset. -`git grep 'rust2-ts: ' ts/runtime` lists them; classify each before fixing. The pointer -comparisons [#584](https://github.com/moq-dev/rust2/pull/584) refuses at translation, where -JS may make two `rs.Place`s for one place, are out of scope: addresses were their route, and -addresses stay refused (decided 2026-11-07 in [the model epic](/quest/m2/ts-model/README.md)). +What remains throws only where translation can't see a pointer's or a byte slice's +origin, since each refusal where the body shows it is already made: -✅ Decided with the maintainer on 2026-11-06 in -[moq-dev/rust2#608](https://github.com/moq-dev/rust2/pull/608): comparing `*const [T]` of -values JS copies moved here from [rs.Slice](/quest/m3/ts-slice-object.md). The options -were to wait on rs.String ([moq-dev/rust2#574](https://github.com/moq-dev/rust2/pull/574)) and run only if `&str` shares -its bytes, or to move it here with the other comparisons left refused (picked). Its only -consumer in moq-net is form_urlencoded 1.2.2's `src/lib.rs:417`, -`debug_assert!(ptr::eq(s.as_bytes(), vec))`, of the `&str` that -`String::from_utf8_lossy(&vec)` borrowed. Under -[moq-dev/rust2#574](https://github.com/moq-dev/rust2/pull/574)'s decision a `&str` stays a -JS string, so `as_bytes` makes fresh bytes and today's refusal is exact; comparing by array -and offset would answer `false` where Rust answers `true`. Look for an exact slower path. +- `rs.arcErase`: a pointer to a value JS copies cast to `*const ()`, which isn't an `Arc`'s + or `Rc`'s raw pointer, so has no one place to compare as. +- `rs.ptrUnerase`: a `*const ()` cast back to a pointer to a type no cast to it was from. + The cast itself is defined; a read through it reads one type's bytes as another's. +- `offset_from` of pointers JS keeps in two arrays, as two `repr(C)` fields or two + `&raw` of one variable are. +- `AtIndex.reach`: a read past the array JS keeps, such as a `repr(C)` neighbour or a + `Vec`'s old values past a `truncate`. +- A raw or mutable slice of a byte in no array of bytes, a field's (a struct's, a + tuple's, a capture's, or one an async body keeps across an `.await`), or a local's whose + address only a call takes, as `ptr::from_mut(&mut b)` does, or a cast of one to + `*const [u8; N]`. A `Uint8Array(1)` per such byte stays within the byte-buffer form, but + any `&mut u8` a callee may turn raw would need one. +- `alloc`'s bytes read or written as bytes, or cast to another type than the one it holds. +- `Bytes::slice_ref` of bytes JS copied where Rust shares them, such as a `&str`'s + `as_bytes`, safe code: a `&str` stays a JS string + ([#574](https://github.com/moq-dev/rust2/pull/574)), so no answer is exact. +- `ptr::eq` of an array `as_chunks` split from one flat slice, which std's callback gets a + copy of, answers `false` where Rust answers `true`, silently (moved here 2026-11-07 in + [#608](https://github.com/moq-dev/rust2/pull/608)). A copy that remembers the slice and + offset it came from, compared through that, is exact; it touches the code + [rs.Slice](/quest/m3/ts-slice-object.md) reworks, so it follows that quest. -✅ Decided with the maintainer on 2026-11-07 in -[moq-dev/rust2#608](https://github.com/moq-dev/rust2/pull/608): `ptr::eq` of an array that -`as_chunks` split from one flat slice, as std lends it to a callback, moved here. Such an -array has no JS array of its own, so `rs.arraySliceItems` gives std a copy of it, and -`ptr::eq` with the array lent elsewhere answers `false` where Rust answers `true`. Arrays -that are each a JS array of their own keep their identity. Look for an exact slower path -with the `*const [T]` comparisons above. +Comparing `*const [T]` of values JS copies (moved here 2026-11-06 in +[#608](https://github.com/moq-dev/rust2/pull/608)) has no exact path: a `&str`'s +`as_bytes` encodes anew each call, so its refusal stays, the exact answer. Public API: the translator's output, and which crates translate. +## Waiting + +- Maintainer: how to treat the pointers above, which only run time sees leave the + pointer forms. Refusing at translation every such construct the body can't show fits, + as the unsafe policy reads, also refuses pointer arithmetic, `offset_from`, raw byte + slices, and `*const ()` casts back on any pointer a parameter or field holds, which work + today; whole-program provenance would refuse exactly the reaching ones, but is a large + analysis. Options: (A) refuse each where the body doesn't show it fits, measured by the + census of moq-net, kio, and the model; (B) keep these run-time checks as the refusal + translation can't make, amending AGENTS.md's "never a runtime failure" for unsafe + pointers from elsewhere; (C) whole-program provenance. Recommended: A for `arcErase` and + `alloc`'s bytes, whose shown routes are narrow and rare; B for the rest, which A would + refuse in most unsafe code that takes a pointer; and B for `slice_ref`, safe code with + no exact answer, rather than a copy that would hide the panic Rust makes on bytes it + doesn't hold. Check: this section records the choice. + ## Related - [Unsafe code the translator can model](/quest/m3/ts-unsafe/README.md) - the raw-pointer model several of these throws guard; its 2026-11-01 run-time failures now follow this quest's rule +- [rs.Slice](/quest/m3/ts-slice-object.md) - reworks the arrays `as_chunks` lends, which the `ptr::eq` gap follows diff --git a/ts/README.md b/ts/README.md index 2e45269bc..50a0f8d77 100644 --- a/ts/README.md +++ b/ts/README.md @@ -110,7 +110,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `Vec` | `rs.Vec`: its items, the array `items`, and the capacity std's holds; `rs.vecFrom(items)` makes one of an array with room for exactly them. `rs.ByteVec` of bytes | | `Cow<[T]>`, `Cow` | `rs.Cow`: the `Vec` it owns, or an `rs.Borrowed` holding the slice it borrows, `rs.Cow>` holding the arrays of a slice of arrays; `rs.ByteCow` for bytes, an `rs.ByteVec` or an `rs.ByteSlice`; `rs.StrCow` for text, the `rs.String` it owns or an `rs.Borrowed` holding the string it borrows, whose text `rs.strCowStr` reads | | `&T`, `&mut T`, `Box`, `Reverse`, `NonZero`, `AssertUnwindSafe` | the value; a `&mut` to a value JS copies, such as a number, an `Option`, or a reference, or to an `Arc`, a `Waker`, or a `LocalKey`, whose copies share what it points at, is an `rs.Place`, which for what a box holds is the place holding the box | -| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling, a read or write through either of which, or through a pointer arithmetic moved off either, aborts, as Rust leaves it undefined. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write, or a mutable slice, through it, which Rust leaves undefined, aborts, as std's debug checks of unsafe preconditions do, while a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers fail at run time, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rs.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | +| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling, a read or write through either of which, or through a pointer arithmetic moved off either, aborts, as Rust leaves it undefined. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write through it, which Rust leaves undefined, aborts, as std's debug checks of unsafe preconditions do, while a mutable slice of it, a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers fail at run time, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rs.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | | `MaybeUninit` | `T`: `undefined` until written, `0` for a byte, or an object whose parts kept as objects are there, holding `undefined`, as `Box::new_uninit` and each of `Box::new_uninit_slice`'s is; a slice's `write_clone_of_slice` clones into its slots without dropping what they held. `Box::new_zeroed`'s holds the value of zero bytes in each part they are one of, such as a number, `false`, `None`, a null pointer, or an enum's variant of a tag or niche of zero, and `undefined` in each part they are none of, such as a reference, for a write to fill before a read | | `ManuallyDrop` | `T`, which nothing drops but its own `drop`; its `Debug`, comparisons, and constants are refused | | `union` | an object of slots named by offset, `at0` and `at8`, each holding the field part kept there; fields must overlap in the same type, or in a non-null pointer and an `Option` of it | @@ -205,19 +205,21 @@ wraps silently. A panic throws `rs.Panic`, with the message native Rust panics w aborts as wasm32's does: it runs no cleanup, so what the translation held is undefined after one, as a wasm trap leaves it, and a caller that catches `rs.Panic` must not use it again. An abort without a panic, as std's for an `RwLock` locked again while held, -throws `rs.Abort`, a `Panic` with std's abort message. So `catch_unwind` only ever returns +throws `rs.Abort`, a `Panic` with std's abort message, as does what Rust leaves undefined +that the runtime catches, such as a read through a dangling pointer, worded as std's debug +checks of unsafe preconditions are, without running the hook. So `catch_unwind` only ever returns `Ok`, `resume_unwind` throws `rs.Abort` without running the hook, and `panic_any` panics with its payload if that is text, or `Box` as std's hook writes any other. A program that reaches `set_hook` has each panic carry the `Location` native code gives it, std's own at the `/rustc//library/...` path its build names, read from the toolchain's source, and runs its hook with a `PanicHookInfo` before throwing; a panic in -the hook throws `rs.Abort`, as std aborts. A panic of `bytes`' own code is where the -program's `bytes` has it, named as the session names that file: by the host's cargo +the hook throws `rs.Abort`, as std aborts. A panic of `bytes`' or tokio's own code is where +the program's copy of that crate has it, named as the session names that file: by the host's cargo registry, unless the build remaps it, as `--remap-path-prefix` does natively. The default hook writes nothing, as wasm32 has no stderr. A program without one passes no locations, and a bundler drops the hook's runtime, `rs/hook.ts`, from it; what stays is the location parameter of the runtime's panicking functions, which it leaves unset, and the key each of -std's and `bytes`' panics passes. +std's, `bytes`', and tokio's panics passes. `Location::caller` gives rustc's location: the file as the session names it, and line and column. A function rustc passes its caller's location to, such as a `#[track_caller]` diff --git a/ts/runtime/rs.ts b/ts/runtime/rs.ts index 3a19c603e..5bdae6010 100644 --- a/ts/runtime/rs.ts +++ b/ts/runtime/rs.ts @@ -319,7 +319,7 @@ class TextAt extends AtIndex { } } -/** A write, or a mutable slice, through a `TextAt`, which a shared reference made. */ +/** A write through a `TextAt`, which a shared reference made. */ function textWrite(): never { return violated("a write requires a pointer not made from a shared reference, as `str::as_ptr`'s is"); } @@ -679,7 +679,9 @@ export function ptrByteSlice(p: Place, len: number, shared: boolean): By } const at = elemOf(p); at.reach(len); - if (!shared && len !== 0 && at instanceof TextAt) textWrite(); + // Stacked Borrows makes it undefined, though Tree Borrows allows it until a write, as + // with a substring's pointer moved back into its text, which throws until Rust settles. + if (!shared && len !== 0 && at instanceof TextAt) throw new Error("rust2-ts: a mutable slice of a `str`'s bytes through `str::as_ptr`"); if (at.array instanceof Uint8Array) return new ByteSlice(at.array, at.index, len); // A byte in no array, which no `Uint8Array` can share. if (!shared) throw new Error("rust2-ts: a raw or mutable slice of a byte in no array of bytes"); diff --git a/ts/tests/pointers.ts b/ts/tests/pointers.ts index 5c627df67..a1fa48f52 100644 --- a/ts/tests/pointers.ts +++ b/ts/tests/pointers.ts @@ -157,8 +157,8 @@ assert.equal(rs.arcErase(rs.NULL, "bool", 1), rs.NULL); assert.throws(() => rs.arcErase({ v: false }, "bool", 1), /only an `Arc`'s or `Rc`'s raw pointer keeps the place of/); // A `str`'s UTF-8 through `as_ptr`, which JS encodes anew from its text: read through, -// moved by arithmetic, and viewed, but a write, a copy into it, or a mutable slice of it, -// which Rust forbids, would change nothing the text reads. +// moved by arithmetic, and viewed, but a write or a copy into it, which Rust leaves +// undefined, aborts, and a mutable slice of it, undefined under Stacked Borrows alone, fails. const text = rs.strAsPtr("aé"); assert.equal(rs.ptrAdd(text, 2).v, 0xa9); assert.deepEqual(Array.from(rs.byteSliceView(rs.ptrByteSlice(text, 3, true))), [0x61, 0xc3, 0xa9]); @@ -170,8 +170,8 @@ undefinedBehavior(() => { rs.ptrWrappingAdd(text, 1, 1, 1).v = 0; }); undefinedBehavior(() => rs.ptrCopy(rs.byteSliceAsPtr(rs.byteSliceFrom(Uint8Array.of(1))), rs.ptrAdd(text, 1), 1)); -undefinedBehavior(() => rs.ptrByteSlice(text, 1, false)); -undefinedBehavior(() => new rs.RawSlice(text, 3).derefBytes(false)); +unsure(() => rs.ptrByteSlice(text, 1, false)); +unsure(() => new rs.RawSlice(text, 3).derefBytes(false)); // None of it is nothing written, and two calls' pointers are two encodings. rs.ptrCopy(rs.byteSliceAsPtr(rs.byteSliceFrom(Uint8Array.of(1))), text, 0); assert.equal(rs.ptrByteSlice(text, 0, false).length, 0); From 442020c00dc4258dafa74ce3d09ea5bc96458539 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 15:50:11 -0800 Subject: [PATCH 04/10] fix(ts): skip a crate's panic site in a file its features leave out A hook program whose tokio lacks the sync feature compiles no oneshot.rs, whose panic nothing can reach, so its site is left out rather than refused. Co-Authored-By: Claude Opus 5.5 --- ts/src/lower/caller.rs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/ts/src/lower/caller.rs b/ts/src/lower/caller.rs index a5f1f9f1b..c805d12b2 100644 --- a/ts/src/lower/caller.rs +++ b/ts/src/lower/caller.rs @@ -568,8 +568,9 @@ pub fn sites(t: &mut Translator<'_, '_>, span: Span) -> Expr { Expr::Object(props) } -/// The sites `table` names, in the program's crate `name`: none without one, and an error -/// for versions whose sites differ, as the runtime's panics are one crate's. +/// The sites `table` names, in the program's crate `name`: none without one, nor in a file +/// its features leave out, whose panics nothing reaches, and an error for versions whose +/// sites differ, as the runtime's panics are one crate's. fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateSites) -> Vec<(Key, Expr)> { let tcx = t.tcx; let mut tables: Vec> = Vec::new(); @@ -581,8 +582,9 @@ fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateS let mut props = Vec::new(); for &(key, file, after, needle) in table { match crate_find(tcx, krate, file, after, needle) { - Some(at) => props.push((Key::Name(key.into()), at)), - None => { + None => {} + Some(Some(at)) => props.push((Key::Name(key.into()), at)), + Some(None) => { let after = after.join(" then "); t.err( span, @@ -609,28 +611,32 @@ fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateS } /// The `rs.Location` of the first `needle` after each of `after` in turn in `file`, under -/// `krate`'s `src/`, named as the session names it. +/// `krate`'s `src/`, named as the session names it, if it is there: `None` where the build +/// compiled no such file. fn crate_find( tcx: TyCtxt<'_>, krate: rustc_span::def_id::CrateNum, file: &str, after: &[&str], needle: &str, -) -> Option { +) -> Option> { let map = tcx.sess.source_map(); let suffix = format!("/src/{file}"); let source = (map.files().iter()) .find(|f| f.cnum == krate && self::file(tcx, f).ends_with(&suffix)) .cloned()?; - if !map.ensure_source_file_source_present(&source) { - return None; - } - let text = match &source.src { - Some(src) => src.to_string(), - None => source.external_src.read().get_source()?.to_string(), + let found = || { + if !map.ensure_source_file_source_present(&source) { + return None; + } + let text = match &source.src { + Some(src) => src.to_string(), + None => source.external_src.read().get_source()?.to_string(), + }; + let (line, col) = position(&text, after, needle)?; + Some(object(self::file(tcx, &source), line, col)) }; - let (line, col) = position(&text, after, needle)?; - Some(object(self::file(tcx, &source), line, col)) + Some(found()) } /// Where std's `def_id` panics, if [`CALLEES`] names it. From e21439e895ee4b12c78a1ac86e488ea4136fb3a7 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 15:58:46 -0800 Subject: [PATCH 05/10] fix(ts): find a crate's panic site by the end of its path, as a prefix remap leaves it Co-Authored-By: Claude Opus 5.5 --- ts/src/lower/caller.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ts/src/lower/caller.rs b/ts/src/lower/caller.rs index c805d12b2..af5449e8b 100644 --- a/ts/src/lower/caller.rs +++ b/ts/src/lower/caller.rs @@ -612,7 +612,8 @@ fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateS /// The `rs.Location` of the first `needle` after each of `after` in turn in `file`, under /// `krate`'s `src/`, named as the session names it, if it is there: `None` where the build -/// compiled no such file. +/// compiled no such file. A file is known by the end of its path, its own `src/` or not, as +/// `--remap-path-prefix` rewrites only what comes before it. fn crate_find( tcx: TyCtxt<'_>, krate: rustc_span::def_id::CrateNum, @@ -621,9 +622,15 @@ fn crate_find( needle: &str, ) -> Option> { let map = tcx.sess.source_map(); - let suffix = format!("/src/{file}"); + let suffix = format!("/{file}"); let source = (map.files().iter()) - .find(|f| f.cnum == krate && self::file(tcx, f).ends_with(&suffix)) + .filter(|f| f.cnum == krate) + .filter(|f| { + let name = self::file(tcx, f); + name == file || name.ends_with(&suffix) + }) + // The shortest is the crate's own, rather than one at the same path below another. + .min_by_key(|f| self::file(tcx, f).len()) .cloned()?; let found = || { if !map.ensure_source_file_source_present(&source) { From dfdf4eeacca956b0ceb773b8110ba10fdcb81a25 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 16:54:37 -0800 Subject: [PATCH 06/10] feat(ts)!: locate tokio's oneshot panic from its MIR, and refuse arcErase of a pointer the body doesn't show is an Arc's Tokio's `Receiver::poll` panic site now comes from the `panic!` call in tokio's own MIR at the mapped call, so rustc names the file as native does under any --remap-path-prefix; the source-file text search is gone. The fixtures remap tokio's src/sync to cover it. A pointer to a value JS copies cast to `*const ()` is refused unless the body shows an Arc's or Rc's into_raw or as_ptr gave it, or that it is null or dangling. AGENTS.md allows a loud run-time check for an unsafe pointer from elsewhere, under m3's unsafe policy. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 1 + quest/m3/ts-runtime-throws.md | 83 ++++-------- quest/m3/ts-unsafe/README.md | 4 +- ts/README.md | 11 +- .../lang/panics/hook/expected/hooked.ts | 8 +- .../lang/pointers/expected/pointers.ts | 16 +-- ts/fixtures/lang/pointers/src/pointers.rs | 11 +- ts/fixtures/reject/census.txt | 1 + ts/fixtures/reject/expected.txt | 1 + ts/fixtures/reject/src/pointers.rs | 6 + ts/fixtures/reject/ts.toml | 1 + ts/runtime/rs/task.ts | 5 +- ts/runtime/rs/tokio.ts | 6 +- ts/src/lower/caller.rs | 121 +++++++++--------- ts/src/lower/mir/origin.rs | 63 ++++++++- ts/src/lower/mir/rvalue.rs | 2 +- ts/src/lower/pointer.rs | 3 +- ts/src/lower/tokio.rs | 17 ++- ts/tests/fixtures.rs | 21 ++- 19 files changed, 217 insertions(+), 164 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0a6cb928b..6eb735453 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,7 @@ Each project lives in its own top-level directory; the [quest tree](quest/README # Required - An unsupported construct or malformed input is a compile error with a source span, never a warning, a silent fallback, or a runtime failure. Generated code panics only where the Rust source does. + The one exception is an `unsafe` pointer from elsewhere whose origin translation can't see, such as a parameter's: a loud run-time check may stand in for the refusal, under m3's [unsafe policy](quest/m3/README.md), since refusing every such pointer would refuse pointer arithmetic on any parameter. - Generated output must match the source's semantics exactly: integer widths and overflow, drop order, laziness, and error paths. Prove it with differential tests against native Rust, not by inspection. - Everything is configless, with opinionated names and defaults. Translators take stock crates as they are: no annotations, and no config beyond true platform boundaries. Each config key or source change a consumer needs is a gap to close. - A vanity rename, if ever supported, is opt-in and lives inline in source next to the item, never in a config file. diff --git a/quest/m3/ts-runtime-throws.md b/quest/m3/ts-runtime-throws.md index 2eb6e46c5..833a31150 100644 --- a/quest/m3/ts-runtime-throws.md +++ b/quest/m3/ts-runtime-throws.md @@ -11,72 +11,39 @@ differential tests against native Rust for every construct that now translates. Decided with the maintainer on 2026-11-04: "we should not panic when Rust would not panic", and runtime throws that copy Rust's behaviour are fine. A throw that guards Rust -UB stays, as an abort worded like std's `unsafe precondition(s) violated` check, since -Rust defines nothing there. m3's [unsafe policy](/quest/m3/README.md) (2026-11-07) -supersedes the 2026-11-04 "slower exact path" for `unsafe` gaps: where exactness needs a -new pointer form or pointer metadata, refuse at translation with a span. - -[moq-dev/rust2#661](https://github.com/moq-dev/rust2/pull/661) made the UB guards -`rs.violated` aborts (null, dangling, or moved-off reads and writes, writes through -`str::as_ptr`, `from_raw` of a pointer no `into_raw` gave or of a dropped value, `dealloc` -of memory `alloc` didn't give, a `TrustedLen` zip running out), located std's `Zip` -`unreachable!()` and tokio's oneshot panic in hook programs, and found no other panic a -hook can't locate in a forced-hook survey of the `lang` fixtures. Of `git grep 'rust2-ts: ' -ts/runtime`, these are not gaps: a range's missing `Step` and a fmt width written as a -placeholder (no translation makes either), `rs.u64Of` and its kin given a number past -2^53 (a caller's input), a hook's unlocatable panic (a translator bug guard), and a substring's pointer -read outside its bytes, or a mutable slice through `str::as_ptr` (undefined under Stacked -Borrows; they throw until Rust settles its memory model, decided 2026-11-07 in -[#634](https://github.com/moq-dev/rust2/pull/634)). - -What remains throws only where translation can't see a pointer's or a byte slice's -origin, since each refusal where the body shows it is already made: - -- `rs.arcErase`: a pointer to a value JS copies cast to `*const ()`, which isn't an `Arc`'s - or `Rc`'s raw pointer, so has no one place to compare as. -- `rs.ptrUnerase`: a `*const ()` cast back to a pointer to a type no cast to it was from. - The cast itself is defined; a read through it reads one type's bytes as another's. -- `offset_from` of pointers JS keeps in two arrays, as two `repr(C)` fields or two - `&raw` of one variable are. -- `AtIndex.reach`: a read past the array JS keeps, such as a `repr(C)` neighbour or a - `Vec`'s old values past a `truncate`. -- A raw or mutable slice of a byte in no array of bytes, a field's (a struct's, a - tuple's, a capture's, or one an async body keeps across an `.await`), or a local's whose - address only a call takes, as `ptr::from_mut(&mut b)` does, or a cast of one to - `*const [u8; N]`. A `Uint8Array(1)` per such byte stays within the byte-buffer form, but - any `&mut u8` a callee may turn raw would need one. -- `alloc`'s bytes read or written as bytes, or cast to another type than the one it holds. -- `Bytes::slice_ref` of bytes JS copied where Rust shares them, such as a `&str`'s - `as_bytes`, safe code: a `&str` stays a JS string - ([#574](https://github.com/moq-dev/rust2/pull/574)), so no answer is exact. +UB stays, as an abort worded like std's `unsafe precondition(s) violated` check. + +Decided with the maintainer on 2026-11-07, in +[moq-dev/rust2#661](https://github.com/moq-dev/rust2/pull/661), for the throws that fire +only because translation can't see where a pointer came from: + +- ✅ Refuse at translation, with a span, where the body doesn't show the pointer fits: + `rs.arcErase` (done in #661) and `alloc`'s bytes. +- ✅ Keep as loud run-time checks: `ptrUnerase`, `offset_from` across arrays, + `AtIndex.reach`, raw slices of a field's byte, and `Bytes::slice_ref` of copied bytes, + safe code with no exact answer while a `&str` stays a JS string. AGENTS.md allows the + unsafe ones under m3's [unsafe policy](/quest/m3/README.md). +- Rejected: refusing all of them at translation, which refuses pointer arithmetic on any + pointer parameter; keeping all as run-time checks. + +What remains: + +- `alloc`'s bytes: a byte of memory from `alloc` read or written, or the memory cast to a + type other than the one it holds, throws in `rs/alloc.ts` when the byte pointer reached + there from elsewhere. Refuse at the `alloc` or `realloc` call whose byte pointer the + body doesn't show going only to a typed cast, `dealloc`, `realloc`, or the + `NonNull`/`Option` steps [`alloc_root`](/ts/src/lower/mir/alloc.rs) already follows, so + no untyped pointer leaves the body; and a `realloc` of memory the body cast from one type + whose result it casts to another. This needs a use analysis of that pointer, which the + translator doesn't have yet. The throws in `rs/alloc.ts` are then translator guards. - `ptr::eq` of an array `as_chunks` split from one flat slice, which std's callback gets a copy of, answers `false` where Rust answers `true`, silently (moved here 2026-11-07 in [#608](https://github.com/moq-dev/rust2/pull/608)). A copy that remembers the slice and offset it came from, compared through that, is exact; it touches the code [rs.Slice](/quest/m3/ts-slice-object.md) reworks, so it follows that quest. -Comparing `*const [T]` of values JS copies (moved here 2026-11-06 in -[#608](https://github.com/moq-dev/rust2/pull/608)) has no exact path: a `&str`'s -`as_bytes` encodes anew each call, so its refusal stays, the exact answer. - Public API: the translator's output, and which crates translate. -## Waiting - -- Maintainer: how to treat the pointers above, which only run time sees leave the - pointer forms. Refusing at translation every such construct the body can't show fits, - as the unsafe policy reads, also refuses pointer arithmetic, `offset_from`, raw byte - slices, and `*const ()` casts back on any pointer a parameter or field holds, which work - today; whole-program provenance would refuse exactly the reaching ones, but is a large - analysis. Options: (A) refuse each where the body doesn't show it fits, measured by the - census of moq-net, kio, and the model; (B) keep these run-time checks as the refusal - translation can't make, amending AGENTS.md's "never a runtime failure" for unsafe - pointers from elsewhere; (C) whole-program provenance. Recommended: A for `arcErase` and - `alloc`'s bytes, whose shown routes are narrow and rare; B for the rest, which A would - refuse in most unsafe code that takes a pointer; and B for `slice_ref`, safe code with - no exact answer, rather than a copy that would hide the panic Rust makes on bytes it - doesn't hold. Check: this section records the choice. - ## Related - [Unsafe code the translator can model](/quest/m3/ts-unsafe/README.md) - the raw-pointer model several of these throws guard; its 2026-11-01 run-time failures now follow this quest's rule diff --git a/quest/m3/ts-unsafe/README.md b/quest/m3/ts-unsafe/README.md index 328b9830b..39c266f21 100644 --- a/quest/m3/ts-unsafe/README.md +++ b/quest/m3/ts-unsafe/README.md @@ -62,7 +62,9 @@ construct still open at `b3df54b6c`, all in m3: a byte pointer past its view fail loudly at run time are superseded by [Throw only where Rust panics](/quest/m3/ts-runtime-throws.md) (2026-11-04, #597): where Rust defines the access it translates exactly or is refused with a span, and only a - throw guarding UB stays, as a precondition abort. + throw guarding UB stays, as a precondition abort, or a loud check of a pointer from + elsewhere whose origin translation can't see (2026-11-07, + [#661](https://github.com/moq-dev/rust2/pull/661)). - Done and dropped: a byte pointer past its own `Uint8Array` view. Byte pointers index the whole buffer since [#400](https://github.com/moq-dev/rust2/pull/400) and [#576](https://github.com/moq-dev/rust2/pull/576), and a byte `Vec` keeps its diff --git a/ts/README.md b/ts/README.md index f7452ef45..614fb143f 100644 --- a/ts/README.md +++ b/ts/README.md @@ -110,7 +110,7 @@ crate translation reaches is refused, and so are two versions of one crate it re | `Vec` | `rs.Vec`: its items, the array `items`, and the capacity std's holds; `rs.vecFrom(items)` makes one of an array with room for exactly them. `rs.ByteVec` of bytes | | `Cow<[T]>`, `Cow` | `rs.Cow`: the `Vec` it owns, or an `rs.Borrowed` holding the slice it borrows, `rs.Cow>` holding the arrays of a slice of arrays; `rs.ByteCow` for bytes, an `rs.ByteVec` or an `rs.ByteSlice`; `rs.StrCow` for text, the `rs.String` it owns or an `rs.Borrowed` holding the string it borrows, whose text `rs.strCowStr` reads | | `&T`, `&mut T`, `Box`, `Reverse`, `NonZero`, `AssertUnwindSafe` | the value; a `&mut` to a value JS copies, such as a number, an `Option`, or a reference, or to an `Arc`, a `Waker`, or a `LocalKey`, whose copies share what it points at, is an `rs.Place`, which for what a box holds is the place holding the box | -| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling, a read or write through either of which, or through a pointer arithmetic moved off either, aborts, as Rust leaves it undefined. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write through it, which Rust leaves undefined, aborts, as std's debug checks of unsafe preconditions do, while a mutable slice of it, a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers fail at run time, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, which `rs.arcErase` checks where the body doesn't show it, and refused where the body shows a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | +| `*const T`, `*mut T`, `NonNull` | what a `&mut T` is: the object, an `rs.Slice` of a `[T; N]`'s elements or an `rs.ByteSlice` of a `[u8; N]`'s bytes, which compares by the array or buffer and offset they are at, refused for an array of one, which `array::from_ref`, `from_mut` of a variable, and `Option::as_slice` make of their own, or an `rs.Place` to a value JS copies and to a library type such as a `Vec` or an `Arc`, which into an array, slice, or `Vec` is the `rs.AtIndex` of its element, which `add`, `sub`, `offset`, their wrapping forms, `offset_from`, `ptr::copy`, `write_bytes` of bytes, and `slice::from_raw_parts` move, measure, copy between, set, and view; one to a value in no array is element 0 of an array of one, as in Rust, but a byte variable whose `&raw` the body takes, or that of a reference to it made there, as `&mut b as *mut u8` does, or of whose `&mut` it makes a slice of one, is element 0 of a `Uint8Array` of its own, which its raw, mutable, and shared slices view as they do any other bytes; JS keeps an array of one, and a shared subslice of a byte in no array, which JS copies, apart from what holds it in Rust, so a pointer, slice, copy, or write of bytes the body shows reaching past either, and `offset_from` between pointers the body shows JS keeps in different arrays, are refused, and through a pointer from elsewhere any of these, a raw or mutable slice of a byte in no array, such as a field's, or a read or write past the array JS keeps it in but for a `Vec`'s room up to its capacity, fails at run time; a pointer into an array of values JS keeps as objects is refused, as is comparing pointers to other values JS copies, each a place JS makes of its own; `rs.NULL` for null and `rs.DANGLING` for dangling, a read or write through either of which, or through a pointer arithmetic moved off either, aborts, as Rust leaves it undefined. `str::as_ptr` points into the text's UTF-8, which JS encodes anew at each call, so a read through it reads what Rust's does and a write through it, which Rust leaves undefined, aborts, as std's debug checks of unsafe preconditions do, while a mutable slice of it, a read before its first byte, such as a substring's pointer moved back into its text's bytes, and `offset_from` between two calls' pointers fail at run time, each refused where the body shows it. A pointer to a slice cast to one to an array of its elements is the `rs.Slice` or `rs.ByteSlice` of that many from its first, read through only where Rust reads. A `*const ()` is an identity, such as a waker's data, and `rs.DANGLING_UNIT` when dangling; one to a place of `()` or from a reference to one is refused. A pointer to a value JS keeps as an object cast to one, by `as` or `cast`, is the same object, which `rs.ptrErase` notes the type of, so a cast back to a pointer to another type fails at run time, and null and dangling stay so, dangling at the alignment of the type it was cast from; one to a value JS copies is the same place where an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its value's one place, and refused where the body doesn't show one of those gave it, or null or dangling, such as a borrow's, a new place each borrow, as is casting one to a view of bytes, a new one each borrow, or one of no fixed size. A write of a whole object copies into it one object deep, as an assignment through a `&mut` does, the state an `rs` class such as `rs.LazyCell` keeps private included, so a pointer to a part kept as an object, such as a field of a tuple or struct type, is refused wherever the crate may put another object there while a pointer into that memory may still be read, which a write into a fresh allocation, or a variable before any pointer into it is taken, can't, whether by index or through std's iterators over its slots; a read copies what the crate writes into in place | | `MaybeUninit` | `T`: `undefined` until written, `0` for a byte, or an object whose parts kept as objects are there, holding `undefined`, as `Box::new_uninit` and each of `Box::new_uninit_slice`'s is; a slice's `write_clone_of_slice` clones into its slots without dropping what they held. `Box::new_zeroed`'s holds the value of zero bytes in each part they are one of, such as a number, `false`, `None`, a null pointer, or an enum's variant of a tag or niche of zero, and `undefined` in each part they are none of, such as a reference, for a write to fill before a read | | `ManuallyDrop` | `T`, which nothing drops but its own `drop`; its `Debug`, comparisons, and constants are refused | | `union` | an object of slots named by offset, `at0` and `at8`, each holding the field part kept there; fields must overlap in the same type, or in a non-null pointer and an `Option` of it | @@ -213,13 +213,14 @@ with its payload if that is text, or `Box` as std's hook writes any oth A program that reaches `set_hook` has each panic carry the `Location` native code gives it, std's own at the `/rustc//library/...` path its build names, read from the toolchain's source, and runs its hook with a `PanicHookInfo` before throwing; a panic in -the hook throws `rs.Abort`, as std aborts. A panic of `bytes`' or tokio's own code is where -the program's copy of that crate has it, named as the session names that file: by the host's cargo -registry, unless the build remaps it, as `--remap-path-prefix` does natively. The default +the hook throws `rs.Abort`, as std aborts. A panic of `bytes`' own code is where the +program's `bytes` has it, and one of tokio's where its compiled code has it, named as the +session names that file: by the host's cargo registry, unless the build remaps it, as +`--remap-path-prefix` does natively. The default hook writes nothing, as wasm32 has no stderr. A program without one passes no locations, and a bundler drops the hook's runtime, `rs/hook.ts`, from it; what stays is the location parameter of the runtime's panicking functions, which it leaves unset, and the key each of -std's, `bytes`', and tokio's panics passes. +std's and `bytes`' panics passes. `Location::caller` gives rustc's location: the file as the session names it, and line and column. A function rustc passes its caller's location to, such as a `#[track_caller]` diff --git a/ts/fixtures/lang/panics/hook/expected/hooked.ts b/ts/fixtures/lang/panics/hook/expected/hooked.ts index c096e8213..ef810dc01 100644 --- a/ts/fixtures/lang/panics/hook/expected/hooked.ts +++ b/ts/fixtures/lang/panics/hook/expected/hooked.ts @@ -87,7 +87,7 @@ export function hook(): void { captured(info); }, (): void => { rs.drop(captured); - }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); + }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); } export function tracked(n: rs.u8, caller: rs.Location): rs.u8 { @@ -220,7 +220,7 @@ export function aborted(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void } }, (): void => { rs.drop(captured2); - }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); + }), { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); rs.byteVecPush(out, n); const _13: rs.u8 = rs.u8Rem(kind, 5, { file: "fixtures/lang/panics/src/hooked.rs", line: 174, col: 11 }); if (_13 === 3 || _13 === 4) { @@ -661,7 +661,7 @@ export function stock(kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): void { rs.stringPushStr(note, line.v); }, { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/thread/local.rs", line: 721, col: 38 }); rs.panicFmt(["unread"], { file: "fixtures/lang/panics/src/hooked.rs", line: 466, col: 13 }); - }, { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 }, tokio_oneshot_poll: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.54.1/src/sync/oneshot.rs", line: 1291, col: 13 } }); + }, { capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/raw_vec/mod.rs", line: 29, col: 5 }, trusted_capacity: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/spec_from_iter_nested.rs", line: 57, col: 18 }, swap_remove: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2178, col: 13 }, vec_set_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 2138, col: 9 }, into_flattened: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/vec/mod.rs", line: 3667, col: 36 }, rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3902, col: 9 }, rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/mod.rs", line: 3948, col: 9 }, ord_violation: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/slice/sort/shared/smallsort.rs", line: 854, col: 5 }, ord_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cmp.rs", line: 1166, col: 9 }, f32_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f32.rs", line: 1665, col: 9 }, f64_clamp: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/num/f64.rs", line: 1643, col: 9 }, encode_utf8: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2507, col: 9 }, encode_utf16: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/char/methods.rs", line: 2601, col: 13 }, format: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/fmt.rs", line: 657, col: 14 }, to_string: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/string.rs", line: 2997, col: 14 }, debug_struct_fields: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/fmt/mod.rs", line: 2572, col: 9 }, exact_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/exact_size.rs", line: 122, col: 9 }, join_len: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/str.rs", line: 177, col: 10 }, int_sum: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/traits/accum.rs", line: 206, col: 1 }, int_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 554, col: 1 }, char_forward: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/range.rs", line: 119, col: 45 }, hash_capacity: { file: "/cargo/registry/25cdd57fae9f0462/hashbrown-0.17.1/src/raw.rs", line: 36, col: 40 }, btree_range_equal_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 110, col: 21 }, btree_range_equal_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 112, col: 21 }, btree_range_order_BTreeSet: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 119, col: 21 }, btree_range_order_BTreeMap: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/btree/search.rs", line: 121, col: 21 }, deque_insert: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2612, col: 9 }, deque_swap_i: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1062, col: 9 }, deque_swap_j: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 1063, col: 9 }, deque_rotate_left: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3198, col: 9 }, deque_rotate_right: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 3243, col: 9 }, deque_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/vec_deque/mod.rs", line: 2724, col: 9 }, list_split_off: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/alloc/src/collections/linked_list.rs", line: 1015, col: 9 }, mutex_lock: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sys/sync/mutex/no_threads.rs", line: 28, col: 9 }, once_force: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/std/src/sync/once.rs", line: 227, col: 20 }, reentrant_init: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/once.rs", line: 325, col: 66 }, lazy_poisoned: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/cell/lazy.rs", line: 386, col: 5 }, ready_poll: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 23, col: 35 }, ready_into_inner: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/future/ready.rs", line: 46, col: 16 }, duration_new: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 281, col: 18 }, duration_from_mins: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 540, col: 13 }, duration_from_hours: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 510, col: 13 }, duration_add: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1345, col: 31 }, duration_sub: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1365, col: 31 }, duration_mul: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/time.rs", line: 1385, col: 31 }, zip_next_back: { file: "/rustc/7df81381d027710708209f36b98d11b1c88f8d2e/library/core/src/iter/adapters/zip.rs", line: 213, col: 5 }, bytes_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 207, col: 5 }, bytes_does_not_fit: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/lib.rs", line: 215, col: 5 }, bytes_slice: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 374, col: 28 }, bytes_slice_ref_start: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 426, col: 9 }, bytes_slice_ref_end: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 432, col: 9 }, bytes_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 481, col: 9 }, bytes_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 533, col: 9 }, bytes_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes.rs", line: 694, col: 9 }, bytes_mut_split_off: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 329, col: 9 }, bytes_mut_split_to: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 408, col: 9 }, bytes_mut_set_len: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 545, col: 9 }, bytes_mut_overflow: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 700, col: 21 }, bytes_mut_overflow_offset: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 720, col: 29 }, bytes_mut_buf_advance: { file: "/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.12.1/src/bytes_mut.rs", line: 1246, col: 9 } }); const subset: rs.ByteSlice = rs.bytesSlice(whole, 0, 1); if (k === 0) { const _22: rs.ByteSlice = rs.bytesSlice(whole, rs.usizeAdd(1, rs.usizeRem(at, 2, { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 34 }), { file: "fixtures/lang/panics/src/hooked.rs", line: 470, col: 30 })); @@ -862,7 +862,7 @@ export function tokioStock(_kind: rs.u8, data: rs.ByteSlice, out: rs.ByteVec): v let iterStart: rs.i32 = 0; const iterEnd: rs.i32 = 2; while (iterStart++ < iterEnd) { - const _21: rs.Poll> = rs.oneshotPoll(rx, cx, { _0: undefined }); + const _21: rs.Poll> = rs.oneshotPoll(rx, cx, { _0: undefined }, { file: "tokio/channels/oneshot.rs", line: 1291, col: 13 }); if (_21 !== rs.Pending) { if (_21.ok) { rs.byteVecPush(out, _21.value); diff --git a/ts/fixtures/lang/pointers/expected/pointers.ts b/ts/fixtures/lang/pointers/expected/pointers.ts index 5e9b3d68b..fcf9bb37d 100644 --- a/ts/fixtures/lang/pointers/expected/pointers.ts +++ b/ts/fixtures/lang/pointers/expected/pointers.ts @@ -2742,16 +2742,12 @@ export function flagWaker(flag: rs.Arc>): rs.Waker { return rs.wakerFromRaw({ data: rs.arcErase(rs.arcRaw(arc, rs.arcPlace(arc), "Arc"), "std::sync::atomic::Atomic", 1), vtable: FLAG }); } -/** `p`, a pointer this body doesn't show the source of, erased. */ -export function eraseFlag(p: rs.Place>): rs.Place { - return rs.arcErase(p, "std::sync::atomic::Atomic", 1); -} - /** * The raw pointers of `Arc`s and `Rc`s of values JS copies: a number's remade from a * shared reference to its value, counted up and down, cloned, and taken back through it, * and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its - * vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives. + * vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a + * null one as null. */ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const num: rs.Arc = new rs.Arc(data.length as rs.u32); @@ -2819,7 +2815,7 @@ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const arc2 = rc; const _116: boolean = _117 === rs.arcErase(rs.arcRaw(arc2, rs.arcPlace(arc2), "Rc"), "u16", 2); const arc3 = flag; - rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, eraseFlag(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc")) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place], (a0: boolean): rs.u8 => { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, rs.arcErase(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL], (a0: boolean): rs.u8 => { return a0 ? 1 : 0; })), undefined, true); } @@ -2833,9 +2829,9 @@ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { rs.arcFromRaw(rs.arcRaw(rc, rs.arcPlace(rc), "Rc"), "Rc")[Symbol.dispose](); } rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(num.strong & 0xff, rc.strong & 0xff, rc.value & 0xff)), undefined, true); - const _169: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; - const first: Shelf.Shelf = _169[0]; - const second: Shelf.Shelf = _169[1]; + const _173: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; + const first: Shelf.Shelf = _173[0]; + const second: Shelf.Shelf = _173[1]; let shelf: Shelf.Shelf = first; const value: rs.u32 = shelf._0.value; if (isSomeAnd$1s2u5lz(rs.byteSliceFirst(data), (b: rs.u8): boolean => { diff --git a/ts/fixtures/lang/pointers/src/pointers.rs b/ts/fixtures/lang/pointers/src/pointers.rs index 1705c9f96..af2c5a50d 100644 --- a/ts/fixtures/lang/pointers/src/pointers.rs +++ b/ts/fixtures/lang/pointers/src/pointers.rs @@ -2183,15 +2183,11 @@ fn flag_waker(flag: &Arc) -> Waker { unsafe { Waker::from_raw(RawWaker::new(data, &FLAG)) } } -/// `p`, a pointer this body doesn't show the source of, erased. -fn erase_flag(p: *const AtomicBool) -> *const () { - p.cast() -} - /// The raw pointers of `Arc`s and `Rc`s of values JS copies: a number's remade from a /// shared reference to its value, counted up and down, cloned, and taken back through it, /// and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its -/// vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives. +/// vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a +/// null one as null. pub fn raw_places(data: &[u8], out: &mut Vec) { let num = Arc::new(data.len() as u32); let rc = Rc::new(9u16); @@ -2236,8 +2232,9 @@ pub fn raw_places(data: &[u8], out: &mut Vec) { [ num_at as *const () == Arc::as_ptr(&num).cast(), rc_at.cast::<()>() == Rc::as_ptr(&rc) as *const (), - erase_flag(Arc::as_ptr(&flag)) == wakers[0].data(), + Arc::as_ptr(&flag).cast::<()>() == wakers[0].data(), ptr::from_ref(&*flag).cast::<()>() == wakers[0].data(), + ptr::null::() as *const () == ptr::null(), ] .map(u8::from), ); diff --git a/ts/fixtures/reject/census.txt b/ts/fixtures/reject/census.txt index 1348aba69..b77179956 100644 --- a/ts/fixtures/reject/census.txt +++ b/ts/fixtures/reject/census.txt @@ -218,6 +218,7 @@ fixtures/reject/src/pointers.rs:erased_empty+2:20: a pointer to `((), ())` cast fixtures/reject/src/pointers.rs:erased_place+2:2: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_place+2:22: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_start+2:2: a pointer to `pointers::Outer` cast to one to `()`, whose address its `pointers::Inner` at its start shares, which JS keeps as an object of its own +fixtures/reject/src/pointers.rs:erased_unshown+1:4: a pointer to `u32` cast to one to `()`, which only an `Arc`'s or `Rc`'s raw pointer keeps the place of, and the body doesn't show this one is fixtures/reject/src/pointers.rs:made_part_replaced+5:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:made_part_replaced+6:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:made_part_replaced+7:58: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of diff --git a/ts/fixtures/reject/expected.txt b/ts/fixtures/reject/expected.txt index 0322a77c5..15f5008d2 100644 --- a/ts/fixtures/reject/expected.txt +++ b/ts/fixtures/reject/expected.txt @@ -220,6 +220,7 @@ fixtures/reject/src/pointers.rs:erased_empty+2:20: a pointer to `((), ())` cast fixtures/reject/src/pointers.rs:erased_place+2:2: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_place+2:22: a pointer to `u32` cast to one to `()`, whose JS value is a place of its own each borrow fixtures/reject/src/pointers.rs:erased_start+2:2: a pointer to `pointers::Outer` cast to one to `()`, whose address its `pointers::Inner` at its start shares, which JS keeps as an object of its own +fixtures/reject/src/pointers.rs:erased_unshown+1:4: a pointer to `u32` cast to one to `()`, which only an `Arc`'s or `Rc`'s raw pointer keeps the place of, and the body doesn't show this one is fixtures/reject/src/pointers.rs:made_part_replaced+5:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:made_part_replaced+6:10: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of fixtures/reject/src/pointers.rs:made_part_replaced+7:58: a raw pointer to `(u32, u32)` in `pointers::Gap`, which the crate may put another object in place of diff --git a/ts/fixtures/reject/src/pointers.rs b/ts/fixtures/reject/src/pointers.rs index e309df1c7..c94c783fa 100644 --- a/ts/fixtures/reject/src/pointers.rs +++ b/ts/fixtures/reject/src/pointers.rs @@ -568,6 +568,12 @@ pub fn erased_borrows(n: &u32, c: &std::cell::UnsafeCell, a: &std::sync::Ar std::ptr::from_ref(n) as *const () == arc && c.get().cast_const().cast() == arc } +/// A pointer to a value JS copies from elsewhere, cast to one to `()`, which only an `Arc`'s +/// raw pointer would keep the one place of. +pub fn erased_unshown(p: *const u32) -> *const () { + p.cast() +} + /// A pointer to a box, cast to one to `()`, which JS keeps as what it holds. pub fn erased_box(b: Box<(u8, u8)>) -> bool { let p = &raw const b; diff --git a/ts/fixtures/reject/ts.toml b/ts/fixtures/reject/ts.toml index e71d6f272..e68e537d6 100644 --- a/ts/fixtures/reject/ts.toml +++ b/ts/fixtures/reject/ts.toml @@ -154,6 +154,7 @@ roots = [ "pointers::erased_empty", "pointers::erased_place", "pointers::erased_start", + "pointers::erased_unshown", "pointers::made_part_replaced", "pointers::nonnull_reassigned", "pointers::object_elements", diff --git a/ts/runtime/rs/task.ts b/ts/runtime/rs/task.ts index 0d488e7ef..4518d2166 100644 --- a/ts/runtime/rs/task.ts +++ b/ts/runtime/rs/task.ts @@ -349,8 +349,9 @@ export function arcFromRaw(p: object, of: "Arc" | "Rc"): Arc { /** * `p as *const ()`, as `ptrErase` casts it, of a pointer to a value JS copies: the place * of an `Arc`'s or `Rc`'s value that `into_raw` or `as_ptr` gave, or arithmetic moved back - * to, which is its one place as its address is, or one at no memory. Any other place is a - * borrow's own, which no other pointer to the value would compare as, so it fails. + * to, which is its one place as its address is, or one at no memory. Translation casts + * only one the body shows is either, so any other place, a borrow's own, which no other + * pointer to the value would compare as, fails as its bug. */ export function arcErase(p: object, type: string, align: number): Place { const home = ptrHome(p); diff --git a/ts/runtime/rs/tokio.ts b/ts/runtime/rs/tokio.ts index 0ff5f7792..bc6a2e778 100644 --- a/ts/runtime/rs/tokio.ts +++ b/ts/runtime/rs/tokio.ts @@ -1606,10 +1606,10 @@ export function oneshotTryRecv(rx: OneshotReceiver, empty: E, closed: E return result; } -/** A receiver's `Future::poll`: `Ok` of the value, or `error` once the sender dropped without one. */ -export function oneshotPoll(rx: OneshotReceiver, cx: Context, error: E): Poll> { +/** A receiver's `Future::poll`: `Ok` of the value, or `error` once the sender dropped without one, and a panic at `at` once it gave either. */ +export function oneshotPoll(rx: OneshotReceiver, cx: Context, error: E, at?: Location): Poll> { const inner = rx.inner; - if (inner === undefined) panic("called after complete", "tokio_oneshot_poll"); + if (inner === undefined) panic("called after complete", at); const value = inner.pollRecv(cx); if (value === Pending) return Pending; oneshotFinish(rx); diff --git a/ts/src/lower/caller.rs b/ts/src/lower/caller.rs index af5449e8b..17c1c6338 100644 --- a/ts/src/lower/caller.rs +++ b/ts/src/lower/caller.rs @@ -9,13 +9,15 @@ //! A program that reaches `panic::set_hook` passes where each panic is, which its hook //! reads: each statement's own, the caller's location to each std function that takes it, //! and the call of the macro that defines one, as an integer's methods. A panic in std's -//! own code is where the toolchain's source has it, and one in `bytes`' or `tokio`'s where -//! the program's copy of that crate has it, named as the session names that file, which -//! `rs.setHook` is given. +//! own code is where the toolchain's source has it, and one in `bytes`' where the +//! program's `bytes` has it, named as the session names that file, which `rs.setHook` is +//! given. One in tokio's is where its compiled code has it, passed at the call. use std::sync::OnceLock; +use rustc_attr_ir::LangItem; use rustc_hir::def_id::DefId; +use rustc_middle::mir::TerminatorKind; use rustc_middle::ty::{Instance, InstanceKind, TyCtxt}; use rustc_span::{RemapPathScopeComponents, SourceFile, Span}; @@ -477,14 +479,11 @@ const CALLEES: &[(&str, &str, &str, &str)] = &[ ), ]; -/// Where a crate's code panics, for each of its panics the runtime makes, by the key it +/// Where `bytes`' code panics, for each of its panics the runtime makes, by the key it /// passes in place of a location: a file under the crate's `src/`, the texts before it in -/// turn, and the text the call that panics starts with. -type CrateSites = &'static [(&'static str, &'static str, &'static [&'static str], &'static str)]; - -/// Where `bytes`' code panics. None of its public functions takes its caller's location, so -/// each panic is where its source has it. -const BYTES: CrateSites = &[ +/// turn, and the text the call that panics starts with. None of its public functions takes +/// its caller's location, so each panic is where its source has it. +const BYTES: &[(&str, &str, &[&str], &str)] = &[ ("bytes_advance", "lib.rs", &["fn panic_advance("], "panic!("), ("bytes_does_not_fit", "lib.rs", &["fn panic_does_not_fit("], "panic!("), // `range` takes its caller's location, so its panics are at its call. @@ -537,18 +536,9 @@ const BYTES: CrateSites = &[ ), ]; -/// Where tokio's code panics in what its mapping covers, none of which takes its caller's -/// location. -const TOKIO: CrateSites = &[( - "tokio_oneshot_poll", - "sync/oneshot.rs", - &["impl Future for Receiver", "fn poll("], - "panic!(", -)]; - /// The `rs.Sites` of the toolchain's std, which `rs.setHook` takes: where each panic -/// [`SITES`] names is, as the native build names it, and each [`BYTES`] and [`TOKIO`] name, -/// in the program's `bytes` and `tokio`, if it has them. +/// [`SITES`] names is, as the native build names it, and each [`BYTES`] names, in the +/// program's `bytes`, if it has one. pub fn sites(t: &mut Translator<'_, '_>, span: Span) -> Expr { let tcx = t.tcx; let mut props = Vec::new(); @@ -563,33 +553,30 @@ pub fn sites(t: &mut Translator<'_, '_>, span: Span) -> Expr { } } } - props.extend(crate_sites(t, span, "bytes", BYTES)); - props.extend(crate_sites(t, span, "tokio", TOKIO)); + props.extend(bytes_sites(t, span)); Expr::Object(props) } -/// The sites `table` names, in the program's crate `name`: none without one, nor in a file -/// its features leave out, whose panics nothing reaches, and an error for versions whose -/// sites differ, as the runtime's panics are one crate's. -fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateSites) -> Vec<(Key, Expr)> { +/// The sites [`BYTES`] names, in the program's `bytes`: none without one, and an error for +/// versions whose sites differ, as the runtime's panics are one crate's. +fn bytes_sites(t: &mut Translator<'_, '_>, span: Span) -> Vec<(Key, Expr)> { let tcx = t.tcx; let mut tables: Vec> = Vec::new(); for &krate in tcx.crates(()) { - if tcx.crate_name(krate).as_str() != name { + if tcx.crate_name(krate).as_str() != "bytes" { continue; } tcx.import_source_files(krate); let mut props = Vec::new(); - for &(key, file, after, needle) in table { - match crate_find(tcx, krate, file, after, needle) { - None => {} - Some(Some(at)) => props.push((Key::Name(key.into()), at)), - Some(None) => { + for &(key, file, after, needle) in BYTES { + match bytes_find(tcx, krate, file, after, needle) { + Some(at) => props.push((Key::Name(key.into()), at)), + None => { let after = after.join(" then "); t.err( span, format!( - "the {name} crate's source has no `{needle}` in `src/{file}` after `{after}`, where it panics" + "the bytes crate's source has no `{needle}` in `src/{file}` after `{after}`, where it panics" ), ); } @@ -602,48 +589,62 @@ fn crate_sites(t: &mut Translator<'_, '_>, span: Span, name: &str, table: CrateS if tables.len() > 1 { t.err( span, - format!( - "a panic hook in a program of two versions of the {name} crate, whose panics are at different places" - ), + "a panic hook in a program of two versions of the bytes crate, whose panics are at different places", ); } tables.pop().unwrap_or_default() } /// The `rs.Location` of the first `needle` after each of `after` in turn in `file`, under -/// `krate`'s `src/`, named as the session names it, if it is there: `None` where the build -/// compiled no such file. A file is known by the end of its path, its own `src/` or not, as -/// `--remap-path-prefix` rewrites only what comes before it. -fn crate_find( +/// `krate`'s `src/`, named as the session names it. +fn bytes_find( tcx: TyCtxt<'_>, krate: rustc_span::def_id::CrateNum, file: &str, after: &[&str], needle: &str, -) -> Option> { +) -> Option { let map = tcx.sess.source_map(); - let suffix = format!("/{file}"); + let suffix = format!("/src/{file}"); let source = (map.files().iter()) - .filter(|f| f.cnum == krate) - .filter(|f| { - let name = self::file(tcx, f); - name == file || name.ends_with(&suffix) - }) - // The shortest is the crate's own, rather than one at the same path below another. - .min_by_key(|f| self::file(tcx, f).len()) + .find(|f| f.cnum == krate && self::file(tcx, f).ends_with(&suffix)) .cloned()?; - let found = || { - if !map.ensure_source_file_source_present(&source) { + if !map.ensure_source_file_source_present(&source) { + return None; + } + let text = match &source.src { + Some(src) => src.to_string(), + None => source.external_src.read().get_source()?.to_string(), + }; + let (line, col) = position(&text, after, needle)?; + Some(object(self::file(tcx, &source), line, col)) +} + +/// Where `def_id`, a dependency's function that takes no caller's location, makes its one +/// `panic!`: the call in the MIR its crate compiled, outside what that inlined, whose file is +/// named as the native build names it under any `--remap-path-prefix`. `None` without that +/// MIR, or with other than one such call. +pub fn own_panic(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + if !tcx.is_mir_available(def_id) { + return None; + } + let mir = tcx.optimized_mir(def_id); + let mut spans = mir.basic_blocks.iter().filter_map(|block| { + let terminator = block.terminator(); + let TerminatorKind::Call { func, .. } = &terminator.kind else { return None; - } - let text = match &source.src { - Some(src) => src.to_string(), - None => source.external_src.read().get_source()?.to_string(), }; - let (line, col) = position(&text, after, needle)?; - Some(object(self::file(tcx, &source), line, col)) - }; - Some(found()) + let (callee, _) = func.const_fn_def()?; + let panics = [LangItem::PanicFmt, LangItem::Panic, LangItem::PanicDisplay] + .into_iter() + .any(|item| tcx.is_lang_item(callee, item)); + let own = (terminator.source_info.scope) + .inlined_instance(&mir.source_scopes) + .is_none(); + (panics && own).then_some(terminator.source_info.span) + }); + let span = spans.next()?; + spans.next().is_none().then(|| location(tcx, span)) } /// Where std's `def_id` panics, if [`CALLEES`] names it. diff --git a/ts/src/lower/mir/origin.rs b/ts/src/lower/mir/origin.rs index 839924a07..98fb304e6 100644 --- a/ts/src/lower/mir/origin.rs +++ b/ts/src/lower/mir/origin.rs @@ -6,7 +6,8 @@ //! //! So is whether a pointer to a value JS copies is an `Arc`'s, the one place of its value, //! or a borrow's, a place of its own: only an `Arc`'s is an identity, which `from_raw` -//! takes back to it and a cast to `*const ()` keeps. +//! takes back to it and a cast to `*const ()` keeps. That cast is refused unless the body +//! shows an `Arc`'s, or null or dangling, since a place from elsewhere has no one identity. use rustc_middle::mir::{self, BasicBlock, Local, Location, Operand, ProjectionElem, Rvalue, TerminatorKind}; use rustc_middle::ty::{self, GenericArgsRef}; @@ -99,7 +100,7 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { }) }; match (owner.as_str(), name.as_str()) { - ("ptr" | "NonNull", "cast") => self.erased_borrow(arg(0)?, pointee, gargs.types().nth(1)?), + ("ptr" | "NonNull", "cast") => self.erased_place(arg(0)?, pointee, gargs.types().nth(1)?), ("Arc" | "Rc", "from_raw" | "increment_strong_count" | "decrement_strong_count") if self.arc_pointer(arg(0)?) == Some(false) => { @@ -441,13 +442,61 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { } /// Why the cast of the raw pointer `op` to `from` to one to `to` can't be, if it erases - /// one to a value JS copies that the body shows is a borrow's place to a `*const ()`, and - /// the cast itself refuses no pointer to `from`. - pub(super) fn erased_borrow(&self, op: &Operand<'tcx>, from: ty::Ty<'tcx>, to: ty::Ty<'tcx>) -> Option { + /// one to a value JS copies to a `*const ()`, and the cast itself refuses no pointer to + /// `from`: unless the body shows an `Arc`'s or `Rc`'s `into_raw` or `as_ptr` gave it, its + /// value's one place, or that it is null or dangling, it has no one identity. + pub(super) fn erased_place(&self, op: &Operand<'tcx>, from: ty::Ty<'tcx>, to: ty::Ty<'tcx>) -> Option { let t = &self.b.t; let erases = t.identity_pointee(to) && !t.identity_pointee(from) && t.pointee(from) == Pointee::Place; - (erases && pointer::unerasable(self.b, from).is_none() && self.arc_pointer(op) == Some(false)) - .then(|| pointer::erased_place(t.uninit_inner(from))) + if !erases || pointer::unerasable(self.b, from).is_some() || self.nowhere(op) { + return None; + } + let pointee = t.uninit_inner(from); + match self.arc_pointer(op) { + Some(true) => None, + Some(false) => Some(pointer::erased_place(pointee)), + None => Some(format!( + "a pointer to `{pointee}` cast to one to `()`, which only an `Arc`'s or `Rc`'s raw pointer keeps the place of, and the body doesn't show this one is" + )), + } + } + + /// Whether the body shows the raw pointer `op` is null or dangling, at no memory. + fn nowhere(&self, op: &Operand<'tcx>) -> bool { + let Some(local) = self.traced(op) else { + return false; + }; + if self.def_at[local].is_some() { + return match self.def_rvalue(local) { + Some( + Rvalue::Use(op, _) + | Rvalue::Cast( + mir::CastKind::PtrToPtr + | mir::CastKind::PointerCoercion(ty::adjustment::PointerCoercion::MutToConstPointer, _), + op, + _, + ), + ) => self.nowhere(op), + _ => false, + }; + } + let Some((def_id, _, args)) = self.def_call(local) else { + return false; + }; + match library::key(self.tcx, def_id) { + Some((owner, name)) => match (owner.as_str(), name.as_str()) { + ( + "ptr", + "null" | "null_mut" | "dangling" | "dangling_mut" | "without_provenance" | "without_provenance_mut", + ) + | ("NonNull", "dangling") => true, + ("ptr" | "NonNull", "cast_const" | "cast_mut") | ("NonNull", "as_ptr") => { + args.first().is_some_and(|a| self.nowhere(&a.node)) + } + _ => false, + }, + None => false, + } } /// The local `op` reads whole, if the body assigns it once. diff --git a/ts/src/lower/mir/rvalue.rs b/ts/src/lower/mir/rvalue.rs index 91887cf7d..89091b2ef 100644 --- a/ts/src/lower/mir/rvalue.rs +++ b/ts/src/lower/mir/rvalue.rs @@ -491,7 +491,7 @@ impl<'m, 'b, 'a, 'tcx> Fx<'m, 'b, 'a, 'tcx> { if let (Some(a), Some(b)) = (from.builtin_deref(true), to.builtin_deref(true)) && from.is_raw_ptr() => { - if let Some(why) = self.erased_borrow(op, a, b) { + if let Some(why) = self.erased_place(op, a, b) { return self.err(span, why); } if let Some(cast) = self.alloc_cast(op, a, b, span, out) { diff --git a/ts/src/lower/pointer.rs b/ts/src/lower/pointer.rs index 4c3fc6dbd..e9857c7bd 100644 --- a/ts/src/lower/pointer.rs +++ b/ts/src/lower/pointer.rs @@ -1120,8 +1120,7 @@ pub fn call<'tcx>( /// Why a pointer to `ty` can't be erased to a `*const ()`, an identity that compares as /// itself, if it can't: one JS reaches through a slice's places, or a view of bytes, is a /// new one each borrow, and one to a value of no fixed size loses its size. Of a place, -/// only an `Arc`'s is the value's one, which `rs.arcErase` checks where the body doesn't -/// show it. +/// only an `Arc`'s is the value's one, which the body must show. pub fn unerasable<'tcx>(b: &Body<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { if b.t.polymorphic() && ty.has_param() { return None; diff --git a/ts/src/lower/tokio.rs b/ts/src/lower/tokio.rs index a8469e560..a99f2a5f5 100644 --- a/ts/src/lower/tokio.rs +++ b/ts/src/lower/tokio.rs @@ -428,7 +428,22 @@ pub fn trait_call<'tcx>( let (rx, cx) = (arg(), arg()); let output = b.t.future_output(self_ty.peel_refs(), span); let error = made(b, err_of(output), None, vec![Expr::undefined()], span, out); - Expr::rs("oneshotPoll", vec![rx, cx, error]) + let mut args = vec![rx, cx, error]; + // Where tokio's `poll` panics once it completed, which a hook reads. + if b.t.hooked { + let own = ty::Instance::try_resolve(tcx, b.t.typing_env_pub(), call.def_id, call.args) + .ok() + .flatten() + .and_then(|poll| super::caller::own_panic(tcx, poll.def_id())); + args.push(match own { + Some(at) => at, + None => b.err( + span, + "tokio's `poll` of a oneshot `Receiver`, in a program with a panic hook, whose compiled code shows no one `panic!`", + ), + }); + } + Expr::rs("oneshotPoll", args) } // The rest as std maps them: `Debug` by `fmt`, and `IntoFuture` as itself. _ => return Err(args.collect()), diff --git a/ts/tests/fixtures.rs b/ts/tests/fixtures.rs index fde8f2fb5..d313baf61 100644 --- a/ts/tests/fixtures.rs +++ b/ts/tests/fixtures.rs @@ -59,8 +59,10 @@ fn driver_at(manifest: &Path, config: &Path, args: &[&std::ffi::OsStr], build: & command } -/// The flag that names cargo's home `/cargo` in both builds, so the files of the registry's -/// crates, which a hook's locations name, are named alike on any host. +/// The flags that name cargo's home `/cargo` in both builds, so the files of the registry's +/// crates, which a hook's locations name, are named alike on any host, and tokio's `sync` +/// module `tokio/channels`, a remap of a directory within a crate, which the location of +/// tokio's panic must follow as native does. fn remap() -> String { let home = match std::env::var_os("CARGO_HOME") { Some(home) => PathBuf::from(home), @@ -68,7 +70,20 @@ fn remap() -> String { .expect("a home directory, which holds cargo's") .join(".cargo"), }; - format!("--remap-path-prefix={}=/cargo", home.display()) + let lock = std::fs::read_to_string(manifest_dir().join("Cargo.lock")).unwrap(); + let (_, tokio) = lock + .split_once("name = \"tokio\"\nversion = \"") + .expect("tokio in the lockfile"); + let tokio = format!("tokio-{}", &tokio[..tokio.find('"').unwrap()]); + // The later flag wins where both match. + let mut flags = format!("--remap-path-prefix={}=/cargo", home.display()); + for index in std::fs::read_dir(home.join("registry/src")).into_iter().flatten() { + let sync = index.unwrap().path().join(&tokio).join("src/sync"); + if sync.is_dir() { + flags += &format!(" --remap-path-prefix={}=tokio/channels", sync.display()); + } + } + flags } /// Run the driver on a fixture, returning its output directory and what it printed. From 1ce1437b1ef9f61b4cad4ec4ac921f545ea9b99e Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 16:58:50 -0800 Subject: [PATCH 07/10] fix(ts): word tokio's poll refusal without unlisted code words Co-Authored-By: Claude Opus 5.5 --- ts/src/lower/tokio.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/src/lower/tokio.rs b/ts/src/lower/tokio.rs index a99f2a5f5..57c8a082a 100644 --- a/ts/src/lower/tokio.rs +++ b/ts/src/lower/tokio.rs @@ -439,7 +439,7 @@ pub fn trait_call<'tcx>( Some(at) => at, None => b.err( span, - "tokio's `poll` of a oneshot `Receiver`, in a program with a panic hook, whose compiled code shows no one `panic!`", + "tokio's poll of a oneshot receiver, in a program with a panic hook, whose compiled code shows no one panic", ), }); } From 4b521d934d74cb4cb79b29261ebeb64bdbaebc61 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 17:01:48 -0800 Subject: [PATCH 08/10] fix(ts): quote Rc verbatim in refusals, as Arc is Co-Authored-By: Claude Opus 5.5 --- ts/src/census.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ts/src/census.rs b/ts/src/census.rs index 958b34085..89f6f5e0c 100644 --- a/ts/src/census.rs +++ b/ts/src/census.rs @@ -170,6 +170,7 @@ const VERBATIM: &[&str] = &[ "Pending", "Pointer", "Poll", + "Rc", "Ready", "Reborrow", "Result", From ea6fd01f3beaf0325fd91e7705bddeb978a71d8e Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 17:19:36 -0800 Subject: [PATCH 09/10] fix(ts): erase a constant null pointer, and fetch crates before remapping tokio's sync Co-Authored-By: Claude Opus 5.5 --- ts/fixtures/lang/pointers/expected/pointers.ts | 10 +++++----- ts/fixtures/lang/pointers/src/pointers.rs | 6 +++++- ts/src/lower/mir/origin.rs | 7 +++++++ ts/tests/fixtures.rs | 13 +++++++++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ts/fixtures/lang/pointers/expected/pointers.ts b/ts/fixtures/lang/pointers/expected/pointers.ts index fcf9bb37d..683b06d4d 100644 --- a/ts/fixtures/lang/pointers/expected/pointers.ts +++ b/ts/fixtures/lang/pointers/expected/pointers.ts @@ -2747,7 +2747,7 @@ export function flagWaker(flag: rs.Arc>): rs.Waker { * shared reference to its value, counted up and down, cloned, and taken back through it, * and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its * vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a - * null one as null. + * null one, made here or a constant, as null. */ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const num: rs.Arc = new rs.Arc(data.length as rs.u32); @@ -2815,7 +2815,7 @@ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const arc2 = rc; const _116: boolean = _117 === rs.arcErase(rs.arcRaw(arc2, rs.arcPlace(arc2), "Rc"), "u16", 2); const arc3 = flag; - rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, rs.arcErase(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL], (a0: boolean): rs.u8 => { + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, rs.arcErase(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL], (a0: boolean): rs.u8 => { return a0 ? 1 : 0; })), undefined, true); } @@ -2829,9 +2829,9 @@ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { rs.arcFromRaw(rs.arcRaw(rc, rs.arcPlace(rc), "Rc"), "Rc")[Symbol.dispose](); } rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(num.strong & 0xff, rc.strong & 0xff, rc.value & 0xff)), undefined, true); - const _173: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; - const first: Shelf.Shelf = _173[0]; - const second: Shelf.Shelf = _173[1]; + const _176: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; + const first: Shelf.Shelf = _176[0]; + const second: Shelf.Shelf = _176[1]; let shelf: Shelf.Shelf = first; const value: rs.u32 = shelf._0.value; if (isSomeAnd$1s2u5lz(rs.byteSliceFirst(data), (b: rs.u8): boolean => { diff --git a/ts/fixtures/lang/pointers/src/pointers.rs b/ts/fixtures/lang/pointers/src/pointers.rs index af2c5a50d..a8ec6e72a 100644 --- a/ts/fixtures/lang/pointers/src/pointers.rs +++ b/ts/fixtures/lang/pointers/src/pointers.rs @@ -2183,11 +2183,14 @@ fn flag_waker(flag: &Arc) -> Waker { unsafe { Waker::from_raw(RawWaker::new(data, &FLAG)) } } +/// A null pointer to a number, as a constant. +const NULL_NUM: *const u32 = ptr::null(); + /// The raw pointers of `Arc`s and `Rc`s of values JS copies: a number's remade from a /// shared reference to its value, counted up and down, cloned, and taken back through it, /// and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its /// vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a -/// null one as null. +/// null one, made here or a constant, as null. pub fn raw_places(data: &[u8], out: &mut Vec) { let num = Arc::new(data.len() as u32); let rc = Rc::new(9u16); @@ -2235,6 +2238,7 @@ pub fn raw_places(data: &[u8], out: &mut Vec) { Arc::as_ptr(&flag).cast::<()>() == wakers[0].data(), ptr::from_ref(&*flag).cast::<()>() == wakers[0].data(), ptr::null::() as *const () == ptr::null(), + NULL_NUM.cast::<()>() == ptr::null(), ] .map(u8::from), ); diff --git a/ts/src/lower/mir/origin.rs b/ts/src/lower/mir/origin.rs index 98fb304e6..2cfde291f 100644 --- a/ts/src/lower/mir/origin.rs +++ b/ts/src/lower/mir/origin.rs @@ -463,6 +463,13 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { /// Whether the body shows the raw pointer `op` is null or dangling, at no memory. fn nowhere(&self, op: &Operand<'tcx>) -> bool { + // A constant pointer of no allocation, an integer: null, or another, which a + // constant's lowering refuses. + if let Operand::Constant(c) = op { + return (c.const_) + .try_eval_scalar_int(self.tcx, self.b.t.typing_env_pub()) + .is_some(); + } let Some(local) = self.traced(op) else { return false; }; diff --git a/ts/tests/fixtures.rs b/ts/tests/fixtures.rs index d313baf61..0f3465a7b 100644 --- a/ts/tests/fixtures.rs +++ b/ts/tests/fixtures.rs @@ -64,6 +64,19 @@ fn driver_at(manifest: &Path, config: &Path, args: &[&std::ffi::OsStr], build: & /// module `tokio/channels`, a remap of a directory within a crate, which the location of /// tokio's panic must follow as native does. fn remap() -> String { + static FLAGS: std::sync::OnceLock = std::sync::OnceLock::new(); + FLAGS.get_or_init(remap_flags).clone() +} + +/// The flags [`remap`] gives, once the lockfile's crates are unpacked, so they don't +/// depend on what a build before unpacked. +fn remap_flags() -> String { + let status = cargo() + .args(["fetch", "--locked", "--manifest-path"]) + .arg(workspace()) + .status() + .expect("running cargo"); + assert!(status.success(), "fetching the fixtures' crates failed"); let home = match std::env::var_os("CARGO_HOME") { Some(home) => PathBuf::from(home), None => std::env::home_dir() From af39ba68ac1153edbc94c3596787b6c70d9154f8 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Sat, 7 Nov 2026 17:26:25 -0800 Subject: [PATCH 10/10] fix(ts): follow ptr and NonNull casts to a pointer's null or Arc origin Co-Authored-By: Claude Opus 5.5 --- .../lang/pointers/expected/pointers.ts | 22 +++++++++++++------ ts/fixtures/lang/pointers/src/pointers.rs | 4 +++- ts/src/lower/mir/origin.rs | 16 +++++++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ts/fixtures/lang/pointers/expected/pointers.ts b/ts/fixtures/lang/pointers/expected/pointers.ts index 683b06d4d..c735d1481 100644 --- a/ts/fixtures/lang/pointers/expected/pointers.ts +++ b/ts/fixtures/lang/pointers/expected/pointers.ts @@ -2747,7 +2747,7 @@ export function flagWaker(flag: rs.Arc>): rs.Waker { * shared reference to its value, counted up and down, cloned, and taken back through it, * and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its * vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a - * null one, made here or a constant, as null. + * null one, made here or a constant, as null, through casts to and from `MaybeUninit`. */ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const num: rs.Arc = new rs.Arc(data.length as rs.u32); @@ -2815,23 +2815,31 @@ export function rawPlaces(data: rs.ByteSlice, out: rs.ByteVec): void { const arc2 = rc; const _116: boolean = _117 === rs.arcErase(rs.arcRaw(arc2, rs.arcPlace(arc2), "Rc"), "u16", 2); const arc3 = flag; - rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, rs.arcErase(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL, rs.arcErase(rs.NULL, "u32", 4) === rs.NULL], (a0: boolean): rs.u8 => { + const _121: boolean = rs.arcErase(rs.arcRaw(arc3, rs.arcPlace(arc3), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place; + const _128: boolean = rs.arcErase(rs.arcRaw(flag, rs.arcPlace(flag), "Arc"), "std::sync::atomic::Atomic", 1) === wakers.items[rs.idx(wakers.items, 0)].data as rs.Place; + const _136: boolean = rs.arcErase(rs.NULL, "u32", 4) === rs.NULL; + const _140: boolean = rs.arcErase(rs.NULL, "u32", 4) === rs.NULL; + const _143: boolean = rs.arcErase(rs.NULL, "u32", 4) === rs.NULL; + const arc4 = num; + const _149: rs.Place = rs.arcErase(rs.arcRaw(arc4, rs.arcPlace(arc4), "Arc"), "u32", 4); + const arc5 = num; + rs.iterExtendBytes(out, rs.iterSlice(rs.bytesMap([_111, _116, _121, _128, _136, _140, _143, _149 === rs.arcErase(rs.arcRaw(arc5, rs.arcPlace(arc5), "Arc"), "u32", 4)], (a0: boolean): rs.u8 => { return a0 ? 1 : 0; })), undefined, true); } rs.dropVec(wakers); rs.byteVecPush(out, flag.strong & 0xff); while (num.strong > 1) { - const arc4 = num; - rs.arcFromRaw(rs.arcRaw(arc4, rs.arcPlace(arc4), "Arc"), "Arc")[Symbol.dispose](); + const arc6 = num; + rs.arcFromRaw(rs.arcRaw(arc6, rs.arcPlace(arc6), "Arc"), "Arc")[Symbol.dispose](); } while (rc.strong > 1) { rs.arcFromRaw(rs.arcRaw(rc, rs.arcPlace(rc), "Rc"), "Rc")[Symbol.dispose](); } rs.iterExtendBytes(out, rs.iterSlice(Uint8Array.of(num.strong & 0xff, rc.strong & 0xff, rc.value & 0xff)), undefined, true); - const _176: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; - const first: Shelf.Shelf = _176[0]; - const second: Shelf.Shelf = _176[1]; + const _189: [Shelf.Shelf, Shelf.Shelf] = [new Shelf.Shelf(new rs.Arc(1)), new Shelf.Shelf(new rs.Arc(2))]; + const first: Shelf.Shelf = _189[0]; + const second: Shelf.Shelf = _189[1]; let shelf: Shelf.Shelf = first; const value: rs.u32 = shelf._0.value; if (isSomeAnd$1s2u5lz(rs.byteSliceFirst(data), (b: rs.u8): boolean => { diff --git a/ts/fixtures/lang/pointers/src/pointers.rs b/ts/fixtures/lang/pointers/src/pointers.rs index a8ec6e72a..e1e237c6c 100644 --- a/ts/fixtures/lang/pointers/src/pointers.rs +++ b/ts/fixtures/lang/pointers/src/pointers.rs @@ -2190,7 +2190,7 @@ const NULL_NUM: *const u32 = ptr::null(); /// shared reference to its value, counted up and down, cloned, and taken back through it, /// and an `Arc`'s cast to `*const ()` and back, as a waker's data, which its /// vtable counts, wakes, and drops. Each compares as the pointer `as_ptr` gives, and a -/// null one, made here or a constant, as null. +/// null one, made here or a constant, as null, through casts to and from `MaybeUninit`. pub fn raw_places(data: &[u8], out: &mut Vec) { let num = Arc::new(data.len() as u32); let rc = Rc::new(9u16); @@ -2239,6 +2239,8 @@ pub fn raw_places(data: &[u8], out: &mut Vec) { ptr::from_ref(&*flag).cast::<()>() == wakers[0].data(), ptr::null::() as *const () == ptr::null(), NULL_NUM.cast::<()>() == ptr::null(), + ptr::null::>().cast::().cast::<()>() == ptr::null(), + Arc::as_ptr(&num).cast::>().cast::<()>() == Arc::as_ptr(&num).cast(), ] .map(u8::from), ); diff --git a/ts/src/lower/mir/origin.rs b/ts/src/lower/mir/origin.rs index 2cfde291f..4d914d95c 100644 --- a/ts/src/lower/mir/origin.rs +++ b/ts/src/lower/mir/origin.rs @@ -434,6 +434,9 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { ("ptr" | "NonNull", "cast_const" | "cast_mut") | ("NonNull", "as_ptr" | "new_unchecked") => { self.arc_pointer(&args.first()?.node) } + ("ptr" | "NonNull", "cast") if self.same_pointee(&args.first()?.node, local) => { + self.arc_pointer(&args.first()?.node) + } ("UnsafeCell", "get" | "raw_get") | ("Cell", "as_ptr") | ("MaybeUninit", "as_ptr" | "as_mut_ptr") => { Some(false) } @@ -497,7 +500,7 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { "null" | "null_mut" | "dangling" | "dangling_mut" | "without_provenance" | "without_provenance_mut", ) | ("NonNull", "dangling") => true, - ("ptr" | "NonNull", "cast_const" | "cast_mut") | ("NonNull", "as_ptr") => { + ("ptr" | "NonNull", "cast" | "cast_const" | "cast_mut") | ("NonNull", "as_ptr") => { args.first().is_some_and(|a| self.nowhere(&a.node)) } _ => false, @@ -512,9 +515,16 @@ impl<'tcx> Fx<'_, '_, '_, 'tcx> { (self.defs[local] == 1 && !self.is_arg(local)).then_some(local) } - /// Whether `op` is a pointer to what `local` points at. + /// Whether `op` is a pointer, raw or `NonNull`, to what `local` points at, through any + /// `MaybeUninit`s, which a cast between keeps the pointer of. fn same_pointee(&self, op: &Operand<'tcx>, local: Local) -> bool { - let pointee = |ty: ty::Ty<'tcx>| ty.builtin_deref(true); + let pointee = |ty: ty::Ty<'tcx>| { + let pointee = match ty.kind() { + ty::Adt(adt, args) if Std::of(self.tcx, adt.did()) == Some(Std::NonNull) => Some(args.type_at(0)), + _ => ty.builtin_deref(true), + }; + pointee.map(|t| self.b.t.uninit_inner(t)) + }; let from = op.ty(&self.mir.local_decls, self.tcx); pointee(from).is_some() && pointee(from) == pointee(self.mir.local_decls[local].ty) }