Repository navigation
Numbers in any compare by value, whatever types they were boxed with - #535
Merged
Merged
Conversation
`===` and `!==` between two `any`s compared the boxes' bytes, and when the
sizes differed (a `number` and an `s32`) both answered false. So
`isEq(x: any, y: any) { if (x !== y) fail(); }`, the DefaultLib tests'
helper, could never fail on a computed double compared with an integer
literal, which is how `Math.max(-1, -7)` returning 2.2e-308 got past
DefaultLib's tests/math.ts. Loose `==` had no case for two numbers with
different tags either (`1.0 == 1` was false), and orderings compared bytes.
Two numeric `any`s now compare as f64 for every operator: the tag's first
letter says float, unsigned or signed, and the box's data size says the
width. Values of different kinds with different sizes are unequal under
`!==` too, not just under `!=`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 11, 2026
ASDAlexander77
added a commit
that referenced
this pull request
Oct 12, 2026
…558) Every repro in docs/bugs passes on main, or fails as TypeScript does: the native_ts_graphics findings were fixed by #535-#544 and #549 (the `let s = 0` one by design, with a warning since #544), testFallThrough, generic_in_generic and array_of_ifaces_cast by #538, #542 and #543, and bug14 and bug21 aren't valid TypeScript. Each fix has its regression test in tslang/test/tester, and the findings document is in the history and in those PRs, so the folder goes. Its interop notes stay, in docs/c-cpp-header-import.md: a `string` returned by a C function is its `char*`, not a copy; `number` is a `double`; and a nullable `Ref<T>` field is spelled `Ref<T> | null`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
===and!==between twoanyvalues compared the boxes' bytes. When the two boxes had different sizes, e.g. anumberand ans32, both answered false:DefaultLib's
tests/math.tsandtests/shift_ops.tscheck results withisEq(x: any, y: any) { if (x !== y) fail(); }, so a computed double compared with an integer literal could never fail. That is howisEq(Math.max(-1, -7), -1)passed whileMath.maxreturned 2.2e-308 (docs/bugs/ntg_math_max_negative.ts, fixed separately in DefaultLib).Also wrong, in the same code: loose
==between two numbers with different tags (1.0 == 1was false), and</>between numericanys, which compared bytes.Fix
AnyCompareOpLowering: when both tags are of the numeric kind, both values are read as f64 and compared with the operator's float predicate (oeq,une,olt, ...). The tag's first letter says float (f,number), unsigned (u) or signed, and the box's data size says the width. The existing number-unboxing helper only knewnumber,s64ands32; it is now this shared member. For other kinds whose sizes differ,!==now answers true, as!=already did.Testing
00any_number_compare.ts(compile + JIT) covers mixed widths,s64/u8/f32/s16, ordering, NaN, and non-numeric kinds. It fails on the current release (assertion failed: 2.5 !== 1).tests/math.tsrun with this compiler now reportsfail: 2.22507e-308 !== -1(the realMath.maxbug). With that line removed, the rest ofmath.tspasses, and so doesshift_ops.ts, so nothing else was being hidden in those two files.🤖 Generated with Claude Code