Repository navigation
Conversation
Quest-Claim: f91701bdecb3be7b
A `u8` or `MaybeUninit<u8>` local whose `&raw` the body takes, or that of a reference to it made there, is element 0 of a `Uint8Array` of its own, so its raw, mutable, and shared slices, and arrays cast from them, view it. The lone-byte refusals in origin.rs go; a byte in a field still throws at run time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Claims quest/m3/ts-unsafe/lone-byte-buffers.md, planned in moq-dev/rust2#624, and deletes it.
Problem
JS kept a
u8local in no array of bytes, so a raw or mutable slice of it could not be a view of where it is. moq-dev/rust2#624 refused such slices, and casts of them to*const [u8; N], only on the routes itsraw_starttracer followed, and kept missing routes (&raw *s,NonNull::from,NonNull::new(p).unwrap()). The rest threw at run time.Approach
A
u8orMaybeUninit<u8>local whose&rawthe body takes, or whose reference made in the body is cast to a raw pointer (&mut b as *mut u8,let p: *const u8 = &b), is element 0 of aUint8Array(1)of its own (Slot::Byte). Every read and write isb[0], and every pointer to it isrs.arrayAsPtr(b). Its raw, mutable, and shared slices, and casts of them to*const [u8; N], are views of that buffer on every route, andoffset_frombetween its pointers measures them. A parameter keeps its name in the signature and is copied into the buffer on entry.The lone-byte refusals are removed:
Fx::lone_byte_arraywith itsraw_starttracer, andstray's refusal of a raw or mutable slice of a lone byte.Array::Copystays for bytes still in no array, where a shared slice is still an exact copy.Proven by the differential case
pointers::lone_bytesagainst native Rust. It covers each slice and cast route, a parameter,&mut b as *mut u8, a coercion from&c, and aMaybeUninit<u8>.Decisions
.await) throws at run time. Throw only where Rust panics records the gap and owns replacing it with a translation or a refusal: a buffer for each address-takenu8field. Rejected: keeping the refusals for fields only, which is partial route tracing that would be deleted later. Rejected: giving field bytes buffers in this PR.Choices made without asking
&rawthe body takes. A&rawof*r, whereris a reference to the local made once in the body, buffers the local too. That is what&mut b as *mut u8and a coercion to a raw pointer compile to, and without it the most common spelling kept throwing. Calls such asptr::from_mut(&mut b)are not traced and still throw, as they did before this PR (originnever traced them).ts-runtime-throws.mdlists that as well.MaybeUninit<u8>locals are buffered too, sincecrate::lower::bytecounts them as bytes.Overlaps
&raw const *rfor any value JS copies. This PR handles it only for a buffered byte, in the sameRawPtrarm ofrvalue.rs. Whichever lands second resolves the conflict and keeps both: the buffered byte's arm first, then feat(ts): translate a raw pointer behind a reference #621's general one.quest/m3/ts-runtime-throws.md's gap list, and plansslice::from_mut(&mut b)as a quest of its own (that call is refused, not thrown).Caused by
raw_starttracedImpact
Uint8Arrayin generated code, and constructs the reject fixture refused (lone_byte_slices,lone_byte_arrays) now translate. No runtime or wire change.Alternatives
lone_byte_arrayfor bytes in fields: rejected, see Decisions.&mutborrows, which would also cover call routes likeptr::from_mut(&mut b): not taken. It changes the output of every&mut u8local for routes no consumer uses.Validation
quest gate just ci origin/mainafter merging origin/main at fd62edf2c: passed, includinglang::pointers' new differential casepointers::lone_bytesagainst native Rust (89 fixture tests). With moq-dev/rust2#633 on main,UPDATE_EXPECT=1 just ts testleft every snapshot,dynsandpanics/hookincluded, unchanged.quest check --fix: 50 documents ok.Follow-ups
Models
Size: M
Implementer: Claude Code, claude-opus-5-5, high effort
Review
Rewritten by
quest reviewafter each round.01a1b680-72a7-7f00-93a9-494d8a478eed, round 1The buffer approach is sound in principle, but the reference-origin shortcut can silently redirect writes to the wrong byte.ts/src/lower/mir/mod.rs:848:[P2] Exclude mutated references from byte-origin tracing