Skip to content

chore(ts): check stable names on a small fixture of their own - #459

Merged
moq-bot[bot] merged 9 commits into
mainfrom
quest/m0/checks/stable-names
Nov 3, 2026
Merged

moq-bot[bot] merged 9 commits into
mainfrom
quest/m0/checks/stable-names

Conversation

@kixelated

@kixelated kixelated commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Closes quest/m0/checks/stable-names.md.

Problem

stable_names translated all of lang a second time, with fmt::added as an extra root, to check that reaching more instances renames nothing. Since #419 it reuses lang's base translation, but the second translation still costs about one lang translation (130 to 155 CPU-s).

Approach

A new names fixture (5 small modules) keeps every case fmt::added exercised in lang. run reaches one instance of each item. added reaches another instance that sorts before run's:

  • a generic method's (Wrap::new and into_inner at u8)
  • a closure's (Wrap::map over added's closure)
  • an impl's of another trait (Debug beside Display, for Pair and for Wrap<Pair>)
  • a std function's that merges with run's (Option<Ordering>::map_or)
  • an impl's over a deeper &mut (Tally for &mut T)
  • a trait object's module, dyns.Shape, named as the shapes.Shape type that lib.ts imports

stable_names snapshots and type-checks names, then translates it with roots = ["added", "run"] and checks that every base line stays, in order. lang drops fmt::added and refs::deeper (only the doc line of fmt.Padded.ts in its snapshot changes) and no longer shares its translation through a OnceLock.

The fixture has run already call into Pair's module from wrap.Wrap.ts. Otherwise a type-only import type * as Pair becomes a value import once added reaches Debug. That is an import-kind change, not a rename, so I kept kept strict rather than normalizing it.

Each rule is caught

I reintroduced each instability in the translator and ran stable_names with UPDATE_EXPECT=1, so the snapshot can't fail and only the stability check can. Each one fails at the line its case targets:

Instability reintroduced Rule's origin First line stable_names reports changed
A trait impl's function names its trait only when another trait's impl is reached #47 lib.ts: Wrap.fmt(part, f)
A generic instance prints its type arguments only when another instance is reached #47 lib.ts: Wrap.new({ _0: first, _1: 1 })
Closures in a suffix are numbered in reach order #47 lib.ts: Wrap.map$wrap_Pair_u8_closure0(...)
A merged std instance takes the suffix of its first member #265 core/option.ts: mapOr$Option_cmp_Ordering_u8_run_closure0
An import binds its plain name unless the importer already bound one #273 lib.ts: import * as Shape from "./shapes.Shape.ts"
Instances of one item sit in reach order wrap.Wrap.ts: intoInner$u8
Suffixes leave out references, and clashes are numbered #338 tally.ts: tally$tally_Tally_u32$2

CPU

Warm, user plus system CPU-seconds of cargo test --test fixtures -- --exact <tests> on this host:

Run Before (origin/main) After
stable_names alone 262, 308 2.7, 2.8
lang alone 328 to 347 329
lang stable_names together 380, 427, 564 379

Alone, the test drops by about 300 CPU-s. Inside the suite it drops by one lang translation, about 130 to 155 CPU-s (half the two-translation run alone). The together rows are as noisy as that saving, since another build overlapped one of them. Cold matches warm here: the driver always recompiles the fixture, and neither fixture has dependencies.

Impact

  • No public API change.

Alternatives

  • Keep lang as the base and translate only part of it for the added root. The base must match the added run's roots, so it would still cost a second translation of most of lang.
  • Normalize import type in lines() instead of shaping the fixture around it. That would also hide a real type-to-value change in the future.

Follow-ups

  • A result slot's name stays as translation reaches more, planned in this PR under m0's checks: the maintainer moved it there, since unstable names churn snapshots and conflict merges. A slot of Ok parts is named for the first function in source order among those reached, so reaching an earlier one renames readOut to leadOut. I reproduced this on a scratch crate; lang's version of the test never covered it either.

Review

  • Skipped at a8432b53e1162e99e79155b5191941a9cf512874: the only change since round 2 is quest-only. ts-stable-slots.md moved from m3 to quest/m0/checks/ and is listed in that epic's README. just check passed at that head.
  • Codex gpt-6.1-sol, medium effort, round 2 at 7a6c19dc559329a7328a4614af395360e7bdcec6 (after merging origin/main): no findings. Round 1 at a8e1fb47 had none either.
  • just ci passed at 7a6c19dc: lint, quest, ts check, and ts test (12 of 12 fixture tests, 7 of 7 unit tests).

🤖 Generated with Claude Code

kixelated and others added 6 commits November 2, 2026 14:39
stable_names translated all of lang a second time. The names fixture keeps
each case lang's fmt::added reached: another instance of a generic method,
a closure, an impl of another trait, a merged std function, and an impl over
a deeper &mut, each sorting first, beside a trait object's module named as an
imported type's. lang drops fmt::added and refs::deeper, and translates on
its own again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ches more

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Stable names on a small fixture chore(ts): check stable names on a small fixture of their own Nov 3, 2026
@kixelated
kixelated marked this pull request as ready for review November 3, 2026 00:02
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
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: 988ae677-2139-4d51-bec2-41ae7e44dc0e
Commits

Reviewing files that changed from the base of the PR and between 996bc44 and a8432b5.

Files ignored due to path filters: 1
  • ts/Cargo.lock is excluded by !**/*.lock
Files selected for processing: 21
  • quest/m0/checks/README.md
  • quest/m0/checks/stable-names.md
  • quest/m0/checks/ts-stable-slots.md
  • ts/README.md
  • ts/fixtures/lang/expected/fmt.Padded.ts
  • ts/fixtures/lang/src/fmt.rs
  • ts/fixtures/lang/src/refs.rs
  • ts/fixtures/names/Cargo.toml
  • ts/fixtures/names/expected/core/option.ts
  • ts/fixtures/names/expected/lib.ts
  • ts/fixtures/names/expected/shapes.Shape.ts
  • ts/fixtures/names/expected/tally.ts
  • ts/fixtures/names/expected/wrap.Pair.ts
  • ts/fixtures/names/expected/wrap.Wrap.ts
  • ts/fixtures/names/src/dyns.rs
  • ts/fixtures/names/src/lib.rs
  • ts/fixtures/names/src/shapes.rs
  • ts/fixtures/names/src/tally.rs
  • ts/fixtures/names/src/wrap.rs
  • ts/fixtures/names/ts.toml
  • ts/tests/fixtures.rs
Files with no reviewable changes: 1
  • quest/m0/checks/stable-names.md

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The change adds a names fixture with generated TypeScript snapshots for generic wrappers, formatting, shapes, and nested mutable-reference tallying. The stable-names test now checks that adding added as the first root preserves the original generated lines. The lang test translates its fixture locally, and the former lang helper functions are removed. The checklist and documentation now describe preserving result-slot names as translation reaches additional functions.

Merge Risk: Minimal · up to a8432

No actionable merge-blocking issue is established. The dedicated naming fixture appears consistent with the updated stability check; merge after normal checks pass.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "chore(ts): check stable names on a small fixture of their own" matches the main change. The PR adds a dedicated names fixture and a stable_names check that runs on it. It also removes `…
Description check Passed The description is directly related to the changeset. It explains that the names fixture replaces the second lang translation in stable_names. It lists the instability cases the fixture covers, …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "chore(ts): check stable names on a small fixture of their own" matches the main change. The PR adds a dedicated names fixture and a stable_names check that runs on it. It also removes fmt::added and refs::deeper from the lang check. The title does not mention the removal of the lang cases or the OnceLock change, but it names the primary change.

Full details: Description check

Explanation

The description is directly related to the changeset. It explains that the names fixture replaces the second lang translation in stable_names. It lists the instability cases the fixture covers, the CPU measurements, the removal of fmt::added and refs::deeper from lang, and the planned result-slot follow-up. It also reports test results.

Full details: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 8 functions across 14 files. (5 skipped: 5 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • 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 16:02
Unstable names churn snapshots and conflict merges, which the checks epic
exists to cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated enabled auto-merge (squash) November 3, 2026 00:34
@moq-bot
moq-bot Bot merged commit 00a273a into main Nov 3, 2026
@moq-bot
moq-bot Bot deleted the quest/m0/checks/stable-names branch November 3, 2026 00: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