Skip to content

feat(ts): translate std's function values as their calls, mem::take included - #470

Merged
kixelated merged 7 commits into
mainfrom
quest/m3/ts-take-value
Nov 3, 2026
Merged

kixelated merged 7 commits into
mainfrom
quest/m3/ts-take-value

Conversation

@kixelated

@kixelated kixelated commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

rust2-ts refused std functions that write what a &mut borrows when passed as a value, such as v.iter_mut().map(std::mem::take): "unsupported call to std::mem::take::<Vec<u8>>". mem::take, replace, swap, Option::replace, String::push/push_str, Clone::clone_from, u8::make_ascii_uppercase, and the rest of intercept's calls lower only from a MIR call, which has the place. A function value instead got a hand-written arrow over the library mappings, which lack them. The same gap hit f(place, value) inside a generic instantiated with such a function.

Approach

  • A std function value is now an arrow over rustc's reify shim (_0 = f(move _1, ...)), lowered with Fx as any body. Its call goes through the same path as a written call, intercept and the &mut pointee handling included. The shim's spans are moved to the use site, and its arguments are named a0 on, as before.
  • FnOnce::call_once of a mapped std FnDef that takes a &mut calls that value. Other std calls keep the inline call_def, so Option::map(x, From::from) stays x.
  • This deletes the duplicated pointee logic from Body::fn_value. Constructors keep their arrow.
  • A next keeps its call's Option: a shim of std's next no longer takes the item-or-rt.DONE protocol of next's own body, and the crate's own next as a value goes through the shim too instead of being its bare symbol. That bare symbol leaked rt.DONE before this PR.
  • Differential test edits::values: take/replace/swap as values through map, a generic helper, and fn pointers, on bytes (places), objects written in place (Vec), and Strings. It also checks drop order of replaced values against native Rust, plus the other place-writing std calls above as values, and std's and the crate's own next as fn pointers called past the end.

Impact

  • Translator output: these function values now translate. Arrow params and $hash suffixes in snapshots are renumbered where std instances' text changed. No public Rust API change.

Alternatives

  • Expression-level duplicates of each intercepted call for the value path: rejected, as they would duplicate intercept and drift from it.
  • Always calling the shim value from call_once: rejected, because it turns identity conversions in translated std generics into IIFEs.

Follow-ups

Review

  • Codex gpt-6.1-sol, medium effort, via quest review. Latest round 4 on head a4a2935b: no findings.
  • Round 1, [P2] a reify shim of next returned rt.DONE: fixed in 422dc352, along with the same leak for the crate's own next as a value. Both are covered by the differential.
  • Rounds 2 and 3: no findings. Round 4 covers the merges of main, including moq-dev/rust2#474's fixture split. edits::values now lives in ts/fixtures/lang/edits, and the only conflicts were the case registration and regenerated snapshots.

🤖 Generated with Claude Code

kixelated and others added 3 commits November 2, 2026 18:17
Quest-Claim: 7910f226767c4944
std's take, replace, swap, and the other calls that write what a `&mut`
borrows lower only from MIR, so passed as a value they were refused.
Their value is now an arrow of rustc's reify shim, lowered as any body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title mem::take as a function value feat(ts): translate std's function values as their calls, mem::take included Nov 3, 2026
kixelated and others added 2 commits November 2, 2026 19:32
A reify shim of std's `next` took the item-or-`rt.DONE` protocol of
`next`'s own body, and the crate's own `next` as a value was its
symbol, which returns the same; both now return the `Option`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 3, 2026 04:05
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 18 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4937d156-490e-4ac7-9731-7d9da843b7bc
Commits

Reviewing files that changed from the base of the PR and between 3d37327 and a4a2935.

Files selected for processing: 38
  • quest/m3/README.md
  • quest/m3/ts-take-value.md
  • ts/README.md
  • ts/fixtures/codec/expected/harness.ts
  • ts/fixtures/lang/args/expected/args.ts
  • ts/fixtures/lang/borrows/expected/borrows.ts
  • ts/fixtures/lang/boxes/expected/boxes.ts
  • ts/fixtures/lang/clones/expected/clones.ts
  • ts/fixtures/lang/collections/expected/collections.ts
  • ts/fixtures/lang/counts/expected/counts.ts
  • ts/fixtures/lang/cows/expected/cows.ts
  • ts/fixtures/lang/cycles/expected/cycles.ts
  • ts/fixtures/lang/dyns/expected/dyns.ts
  • ts/fixtures/lang/edits/expected/core/bool.ts
  • ts/fixtures/lang/edits/expected/edits.Down.ts
  • ts/fixtures/lang/edits/expected/edits.Logged.ts
  • ts/fixtures/lang/edits/expected/edits.ts
  • ts/fixtures/lang/edits/expected/lib.ts
  • ts/fixtures/lang/edits/src/edits.rs
  • ts/fixtures/lang/edits/src/lib.rs
  • ts/fixtures/lang/errors/expected/errors.ts
  • ts/fixtures/lang/ints/expected/lib.ts
  • ts/fixtures/lang/iters/expected/iters.ts
  • ts/fixtures/lang/joins/expected/joins.ts
  • ts/fixtures/lang/locals/expected/locals.ts
  • ts/fixtures/lang/objects/expected/objects.ts
  • ts/fixtures/lang/orders/expected/orders.ts
  • ts/fixtures/lang/refs/expected/refs.ts
  • ts/fixtures/lang/returns/expected/returns.ts
  • ts/fixtures/lang/sorts/expected/lib.ts
  • ts/fixtures/lang/strs/expected/lib.ts
  • ts/fixtures/lang/zeros/expected/lib.ts
  • ts/fixtures/stock/expected/buf.ts
  • ts/fixtures/stock/expected/harness.ts
  • ts/fixtures/task/expected/drops/objects.ts
  • ts/src/lower/body.rs
  • ts/src/lower/mir/call.rs
  • ts/src/lower/mir/mod.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

kixelated and others added 2 commits November 2, 2026 20:33
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated enabled auto-merge November 3, 2026 04:45
@kixelated
kixelated added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 88d6d21 Nov 3, 2026
5 checks passed
@kixelated
kixelated deleted the quest/m3/ts-take-value branch November 3, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant