Skip to content

feat(ts): replace a captured &mut's object, and default a crate type in place - #204

Merged
kixelated merged 4 commits into
mainfrom
quest/m2/ts-model/places
Oct 29, 2026
Merged

kixelated merged 4 commits into
mainfrom
quest/m2/ts-model/places

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

The model's census still refused two writes through places (quest, found by #168):

  • origin.rs:4052: listing.get_or_insert_default() on an Option<FrontListing>, a crate type. get_or_insert_default only knew std types' defaults.
  • origin.rs:3212: mem::take(&mut in_flight) inside a kio::wait closure that captured the Vec by &mut. Only a capture of a type JS copies read the borrowed place; a capture of an object held the object, so nothing could replace it whole.

The group.rs refusals the quest listed were already cleared by #193.

Approach

  • get_or_insert_default makes its value with default_of, which calls the crate's Default impl when the type isn't std's.
  • Reproducing that turned up a miscompile the call exposes: option_insert tested a place whose held-back definition a call in the then branch could flush into that branch, so the other path read it unset (TypeError on .v). It now materializes what the test reads before branching.
  • A closure captures any &mut alias of a borrowed place as that place, not only one to a value JS copies, so a write of the whole value lands on the caller's variable or field. Passed on whole, the capture is still an rt.Place only for a value JS copies.
  • mem::take/replace through an alias accept a member of an element (pair[1].listed) as an assignable target, which a disjoint field capture yields. Before, this was refused even without a closure.

Tests (differential against native wasm32, each reading the write after):

  • lang refs: get_or_insert_default/get_or_insert_with(Listing::default) of a crate type, through a local, a &mut, and a closure, then reset; mem::take/replace of captured Vec<u8> and Vec<u32>, from a nested closure, of a &mut moved into a move closure, of disjoint tuple fields, and of a field of what a &mut parameter points at.
  • task front: moq's shape. A listing defaulted in place between awaits, and an in-flight Vec held in coroutine state that a kio::wait closure takes and refills each poll, read after the await, and cancelled mid-wait.

With the materialize fix reverted, lang fails with 521 differences.

Census (just ts census):

before after
model 945 943
moq-net 2946 2943
kio 382 382

The cleared refusals are origin.rs:4052 (get_or_insert_default), origin.rs:3212 (mem::take of the captured Vec), and ietf/subscriber.rs:6437 (mem::take(&mut self.properties) in a closure). No refusal was added.

Impact

  • The translator's output only: closures that capture a &mut to an object now read and write the borrowed place. No existing fixture's output changed.

Alternatives

  • Replacing a JS array in place (splice) behind any reference. That would also cover a &mut Vec parameter replaced whole, but it changes what an alias of the old value sees and needs per-kind runtime helpers. A capture of a borrowed place needs neither.

Follow-ups

  • Replacing the value behind a &mut parameter to an object (mem::take(v) with v: &mut Vec<_>, with or without a closure) is still refused: 9 in moq-net, 4 in the model. It's a separate gap from captures.
  • Vec::retain through a place is refused (found while writing the fixture).

🤖 Generated with Claude Code

kixelated and others added 4 commits October 28, 2026 16:51
@kixelated kixelated changed the title Writes through places the model still refuses feat(ts): replace a captured &mut's object, and default a crate type in place Oct 29, 2026
@kixelated
kixelated marked this pull request as ready for review October 29, 2026 03:00
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T03:02:37.378836Z 4092a75 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-29T03:03:40.692607Z 4092a75 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 4092a75bee21c7f3018ce2a2dd6d67a76f78a8cf.

No actionable bugs found. Materializing the option target before branching fixes the lifetime of the generated temporary, and reusing default_of preserves lazy construction while admitting crate-defined defaults. Widening captures only for established borrowed-place aliases is a focused alternative to mutating every JS container in place; existing alias-stability checks remain in force. The generated examples write replacements back to the caller or coroutine state, including disjoint tuple fields, while unsupported whole-object parameter replacement remains refused.

Verification: static review of capture/place/store lowering, default insertion, and the generated synchronous and async/cancellation fixtures, with an independent alias-path check. No builds, differential tests, census, or reported mutation check were run; reported results were not independently reproduced.

(Written by OpenAI)

@kixelated
kixelated merged commit 04ebf23 into main Oct 29, 2026
1 check passed
@kixelated
kixelated deleted the quest/m2/ts-model/places branch October 29, 2026 03:36
kixelated added a commit that referenced this pull request Oct 29, 2026
Co-authored-by: Luke Curley <432854+kixelated@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant