Skip to content

feat(ts): translate the rest of std::future and std::task - #528

Merged
moq-bot[bot] merged 10 commits into
mainfrom
ts-future-task
Nov 3, 2026
Merged

moq-bot[bot] merged 10 commits into
mainfrom
ts-future-task

Conversation

@kixelated

@kixelated kixelated commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

rust2-ts refused parts of the stable std::future and std::task API (found by #519): future::ready and everything on its Ready, Debug of a Poll, Pending, and PollFn, Poll::from, hashing a Poll, a Pending's clone, and Waker::clone_from. No moq consumer calls these; the maintainer plans all of std regardless.

Survey of the stable API: these already translated and stay as they are: pending, poll_fn, IntoFuture (std's and a crate's own), Poll's map, map_ok, map_err, is_ready, is_pending, ==, ordering, Clone, ?, ready!, Context::from_waker and waker, and Waker's wake, wake_by_ref, will_wake, data, vtable, noop, clone, and From<Arc<W>>.

Approach

  • future::ready(v) is a new rt.Ready<T>: an rt.Future whose first poll or into_inner takes v and a later one panics with std's message. A value nothing took drops with it, by the dropper ready is given. It has $move, clone, and Debug (Ready(Some(..)), or Ready(None) once taken), and is a dyn Future as itself.
  • Debug of a Poll is rt.fmtPoll, with rt.OuterPending passed where the Poll holds one that can be pending. Pending and PollFn write their name, as std's do.
  • Hashing a Poll is rt.hashPoll: its variant as an isize, then what it holds, as std's derived Hash writes them.
  • Poll::from(v) is v, as Some(v) already is. Every Pending, whether cloned or made as a zero-sized constant, is rt.NEVER.
  • Waker::clone_from is rt.wakerCloneFrom, one of the runtime's CloneFroms, which clones and drops only where the waker it has would not will_wake the source, as std's does, so a waker in an Option or an array clones over another by it too.
  • Debug of a Waker, Context, or RawWakerVTable writes addresses, so it is now refused with that reason instead of "unsupported call".

Tests: a new lang/futures differential fixture. It covers a Ready polled, awaited, into_innered, cloned before and after its poll, behind a dyn Future, and of (), Option<Option<_>>, and text. Its value's drop order is checked unpolled, dropped, polled, taken, and moved into an async block. Polling it twice panics with `Ready` polled after completion, and into_inner after a poll with std's other message. A Pending never completes over many polls, boxed or cloned. Debug is checked plain, with #, and with width, hex, and zero-pad specs, for nested Poll<Poll<u8>> too. It also hashes Polls, uses them as set keys, and calls clone_from on a waker in a variable and in a field, checking Arc counts and wakes. The reject fixture gains a Ready of a Poll and Debug of a Waker.

Impact

  • Public API: the translator's output. New runtime exports: rt.Ready, rt.fmtPoll, rt.hashPoll, rt.wakerCloneFrom, rt.wakerCloneFromFn. No breaking change.

Alternatives

  • Treating Waker::clone_from as *self = source.clone(): the Arc counts end the same, but a waker an executor gives would see a clone and a drop std never makes.
  • Debug of a Waker with made-up addresses: it could never match native output, so it stays refused.

Follow-ups

  • Wakers made from a RawWaker (new quest): RawWakerVTable::new, RawWaker::new, Waker::from_raw, Waker::new, RawWaker::from(Arc), and == of vtables.
  • Out of std::future/std::task, seen in the survey: AssertUnwindSafe (also a Future) is refused, since it can't be constructed, and String::from_utf8_lossy is an unsupported call. Both are reported for planning.

Review

Codex (quest review, gpt-6.1-sol, medium), round 2 on head 89f62ff reported no findings. That head merges origin/main through #538 after the queue dropped the PR for a conflict: main moved clone_from onto the runtime's CloneFrom functions, so Waker::clone_from is now rt.wakerCloneFrom, an entry of std_clone_from, instead of a special case in mir/call.rs, which also covers a waker in an Option or an array (fixture extended). just ci passes on it. Head cc875dc adds only a conflict-free merge of origin/main (#529); the lang::futures and reject fixtures pass on it, and the full suite is left to the merge queue.

  • Round 1 (head 804a75a): no findings.

🤖 Generated with Claude Code

@kixelated
kixelated marked this pull request as ready for review November 3, 2026 14:54
@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: 42797f6d-f5e9-4dd5-b90b-be4591d819a1
Commits

Reviewing files that changed from the base of the PR and between 8b51ae9 and cc875dc.

Files ignored due to path filters: 1
  • ts/Cargo.lock is excluded by !**/*.lock
Files selected for processing: 30
  • quest/m3/README.md
  • quest/m3/ts-raw-waker.md
  • ts/README.md
  • ts/fixtures/lang/futures/Cargo.toml
  • ts/fixtures/lang/futures/expected/core/option.ts
  • ts/fixtures/lang/futures/expected/core/task/poll.ts
  • ts/fixtures/lang/futures/expected/futures.Count.ts
  • ts/fixtures/lang/futures/expected/futures.Held.ts
  • ts/fixtures/lang/futures/expected/futures.Later.ts
  • ts/fixtures/lang/futures/expected/futures.Logged.ts
  • ts/fixtures/lang/futures/expected/futures.ts
  • ts/fixtures/lang/futures/expected/harness.ts
  • ts/fixtures/lang/futures/expected/lib.ts
  • ts/fixtures/lang/futures/src/futures.rs
  • ts/fixtures/lang/futures/src/lib.rs
  • ts/fixtures/lang/futures/ts.toml
  • ts/fixtures/reject/census.txt
  • ts/fixtures/reject/expected.txt
  • ts/fixtures/reject/src/futures.rs
  • ts/fixtures/reject/ts.toml
  • ts/runtime/rt/task.ts
  • ts/src/lower/collections.rs
  • ts/src/lower/consts.rs
  • ts/src/lower/drop.rs
  • ts/src/lower/fmt.rs
  • ts/src/lower/library.rs
  • ts/src/lower/mir/rvalue.rs
  • ts/src/lower/mod.rs
  • ts/src/lower/task.rs
  • ts/tests/fixtures.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
kixelated enabled auto-merge November 3, 2026 14:58
@kixelated
kixelated added this pull request to the merge queue Nov 3, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 3, 2026
@moq-bot

moq-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

quest land watch: the merge queue removed this pull request at f2d25fb because it conflicts with main (merge_conflict).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

(written by quest land watch)

@moq-bot
moq-bot Bot enabled auto-merge November 3, 2026 15:08
@moq-bot

moq-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

quest land watch: armed auto-merge on this pull request at ad17485, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix (codex / Codex): Merged base and re·solved clone_from conflict preserving Waker and container/slice paths; passed in ts/ with pinned nightly: cargo build --locked -p rust2-ts; cargo test --locked -p rust2-ts; cargo test --locked -p lang-futures-fixture -p reject-fixture; cargo clippy --locked -p rust2-ts --all-targets -- -D warnings; cargo fmt --all --check; tsc -p runtime..

(written by quest land watch)

kixelated and others added 2 commits November 3, 2026 11:23
Waker::clone_from joins main's runtime clone_from, so a waker in an
Option or an array clones over another by it too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 5bafd2d Nov 3, 2026
7 checks passed
@moq-bot
moq-bot Bot deleted the ts-future-task branch November 3, 2026 19:42
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