Skip to content

feat(ts): call a crate's own lt, le, gt, and ge where std does - #173

Merged
kixelated merged 4 commits into
mainfrom
quest/m3/ts-partial-ord
Oct 28, 2026
Merged

kixelated merged 4 commits into
mainfrom
quest/m3/ts-partial-ord

Conversation

@kixelated

@kixelated kixelated commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m3/ts-partial-ord.md.

Problem

#124 refused any comparison that reaches a crate's own PartialOrd::lt, le, gt, or ge through std: sorts, Ord::max/min/clamp, and a tuple's, Arc's, or Reverse's <. std calls the override there; the translation only had partial_cmp.

Approach

  • collections::test_fn builds <T as PartialOrd>::{test} as a JS function: the crate's own where T reaches it (directly, as a tuple's last field, through Arc, through Reverse swapped), else rt.cmpLt/cmpLe/cmpGt/cmpGe over partial_cmp, as the trait's defaults test.
  • A tuple's fields before the last chain by partial_cmp, as std's __chaining_* do (rt.testTuple); an Option and a slice still compare by partial_cmp, as std's do.
  • The runtime's ordMax/ordMin/ordClamp and sorts take those tests rather than a partial_cmp, so one path serves std's types and the crate's. sort/sort_unstable call the new rt.sliceSort (the existing merge sort, exported); cmpArc and cmpReverse widen to tests.
  • The refusal and its reject fixture (Lopsided) are gone.

Differential test: a new keys::overrides lang case with a type whose lt, le, gt, ge each disagree with its partial_cmp, covering direct, tuple (with nested-tuple prefix), Arc, Reverse, Option, max/min/clamp (incl. the min <= max panic), sort, sort_unstable_by_key, and tuple sorts. Forcing test_fn back to partial_cmp makes it fail with 424 differences over 485k cases.

Impact

  • The translator's output: these comparisons translate instead of being refused; default comparisons pass rt.cmpLt(cmp) where they passed cmp.
  • Runtime (breaking, in ts/MIGRATE.md): rt.ordMax, rt.ordMin, rt.sliceSortByKey take an lt; rt.ordClamp takes le, lt, gt; rt.sliceSortBy takes an Ordering comparator only. New: rt.sliceSort, rt.testTuple, rt.cmpLt/cmpLe/cmpGt/cmpGe.

Consumer: moq, whose types derive PartialOrd today; this removes a refusal any stock crate with a hand-written lt hits.

Choices made without asking

  • Unified on tests in the runtime rather than a second override-only path; default output changes from cmp to rt.cmpLt(cmp), with no extra calls per comparison.
  • The std-type < branch keeps its inline partial_cmp test when nothing overrides, for tighter output.

Alternatives

  • Separate runtime entry points for overridden tests: two paths for the same semantics.

Follow-ups

  • std::cmp::max/min (the free functions) are unsupported calls; found writing the test.
  • Conflicts expected with #168 and #149 in snapshots and rt/collections.ts.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 3 commits October 28, 2026 05:40
Quest-Claim: 2db6de1a078aecfd
Sorts, Ord's max, min, and clamp, and a tuple's, Arc's, or Reverse's
comparisons now call the crate's own PartialOrd test where std's do,
rather than refusing it.

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 A crate's own comparison operators feat(ts): call a crate's own lt, le, gt, and ge where std does Oct 28, 2026
@kixelated
kixelated marked this pull request as ready for review October 28, 2026 12:57
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 28, 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-28T13:06:33.085977Z a78c291 New commits
🔒 Security Review ✅ Completed 2026-10-28T13:08:42.202389Z a78c291 New commits
ℹ️ 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: 547a233

No actionable bugs found in the changed lowering, runtime helpers, or differential fixtures. Routing default and overridden comparisons through the same boolean-test interface is a sensible simplification; tuple prefixes retain partial_cmp semantics while the final field, Arc, and Reverse dispatch the appropriate override. The migration note covers the runtime API changes, and the new fixtures exercise all four overrides, nested wrappers, sorting, and clamp's bounds check.

Verification: GitHub source/diff review only; I did not run the translator, TypeScript checks, or differential tests.

# Conflicts:
#	ts/fixtures/lang/expected/harness.ts
#	ts/fixtures/lang/src/harness.rs
@kixelated

Copy link
Copy Markdown
Collaborator Author

Merging: CI passed and Codex reviewed head a78c291 with no findings. quest check against origin/main is clean. No decisions are left open.

Suggested follow-up from the PR body: std::cmp::max/min (the free functions) aren't supported yet.

(Written by Claude Opus 5.5)

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