Skip to content

fix(ts): fold a comparison of two constants a generic function's instance makes - #480

Merged
moq-bot[bot] merged 8 commits into
mainfrom
quest/m3/ts-constant-compares
Nov 3, 2026
Merged

moq-bot[bot] merged 8 commits into
mainfrom
quest/m3/ts-constant-compares

Conversation

@kixelated

@kixelated kixelated commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

An instance of a generic function can compare two constants, such as size_of::<T>() == 1, which u64's instance writes as 8 === 1. tsc refuses an equality of two literal types that differ (TS2367), so the crate fails to translate. Found translating the deque's slices fixture (moq-dev/rust2#443).

It reaches every kind of constant: integers (8 === 2, -1 === -2), chars (99 === 98), floats (1.5 === 0), bools (false === true), a wide integer cast from a narrow one (T::I32 as i128), and a constant folded into a temporary that a comparison then reads (T::U8 / 2 == 1 as 4 === 1).

Approach

The translator already folds comparisons of two number literals, through fold in lower/mir, but only for switch tests and asserts. Now:

  • A comparison rvalue folds as it is lowered, and again where a pending temporary substitutes into it.
  • fold also folds two boolean literals, and reads literals through a source location, as a size_of call's result has one.
  • Expr::not negates a boolean literal to the other, so a folded test reads if (true), not if (!false).

The fold computes what JS would compute at run time from the same two literals, so it keeps the output's semantics. The differential test checks the result against native Rust.

A new lang/constants fixture runs each of the six operators on each kind of constant: size_of, u8, i32, u64, i128, bool, char, f32, f64, casts, and temporaries, plus two ifs. It runs for a T below, equal to, and above the one it compares with, and for one at the limits, NaN, and -0.0. Without the fix, tsc rejects that output with 40+ TS2367 errors.

Other snapshot changes are the same fold showing up in std's code, such as const isSignedTy: boolean = 0 > -128 becoming true. Std instances named by a hash of their text get new names.

Impact

  • The translator's output: a comparison of two literals is written as its value. No API changes.

Alternatives

  • Widen one side, as in (8 as number) === 1. Rejected: noisier output, and it would leave if (8 === 1) for later code to reason about. Folding reuses the existing fold.
  • Fold on the MIR, by evaluating constant operands. Rejected: it misses literals that come from the translator's own arithmetic folds and from temporaries it substitutes.

Follow-ups

  • std::mem::needs_drop::<T>() is refused as an unsupported call, which I found while reproducing this. No quest covers it yet.

Review

mechanical fix by codex / Codex: Merged base, preserving both generated symbol renames and error wrappers; regenerated errors snapshot. Passed in ts/ on nightly-2026-10-15: cargo build --locked -p rust2-ts; UPDATE_EXPECT=1 cargo test --locked -p rust2-ts --test fixtures lang::errors -- --exact; cargo test --locked -p rust2-ts (97 tests). (head 33eca9f)

  • Reviewer: Codex, gpt-6.1-sol, medium effort, via quest review --base origin/main.
  • Round 1 at b4ad4bdd: no findings.
  • Round 2 at a7689cef, after merging main's per-module split of the lang fixture (moq-dev/rust2#474): no findings.
  • Since then, only conflict-free merges of main up to c8e03978. Snapshots were regenerated with no changes, and just ci passed at f8439ed0.

🤖 Generated with Claude Code

kixelated and others added 5 commits November 2, 2026 19:42
…ance makes

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

# Conflicts:
#	ts/fixtures/lang/expected/harness.ts
#	ts/fixtures/lang/src/harness.rs
…compares

# Conflicts:
#	ts/fixtures/lang/errors/expected/errors.ts
#	ts/fixtures/lang/expected/harness.ts
#	ts/fixtures/lang/ints/expected/ints.ts
#	ts/fixtures/lang/shapes/expected/constants.ts
#	ts/fixtures/lang/shapes/src/constants.rs
#	ts/fixtures/lang/src/harness.rs
#	ts/fixtures/lang/src/lib.rs
#	ts/fixtures/lang/strs/expected/core/str.ts
#	ts/fixtures/lang/strs/expected/strs.ts
@kixelated kixelated changed the title A comparison of two constants fix(ts): fold a comparison of two constants a generic function's instance makes Nov 3, 2026
@kixelated
kixelated marked this pull request as ready for review November 3, 2026 04:45
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

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: d098de3d-ddc6-4cf5-8346-e675c3f3123e
  • 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 05:03
@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 f8439ed 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 05:15
@moq-bot

moq-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

quest land watch: armed auto-merge on this pull request at 33eca9f, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix (codex / Codex): Merged base, preserving both generated symbol renames and error wrappers; regenerated errors snapshot. Passed in ts/ on nightly-2026-10-15: cargo build --locked -p rust2-ts; UPDATE_EXPECT=1 cargo test --locked -p rust2-ts --test fixtures lang::errors -- --exact; cargo test --locked -p rust2-ts (97 tests)..

(written by quest land watch)

@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit e81934e Nov 3, 2026
5 checks passed
@moq-bot
moq-bot Bot deleted the quest/m3/ts-constant-compares branch November 3, 2026 05:21
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