Skip to content

Conversation

@JeremyMoeglich
Copy link
Contributor

Disclaimer: large parts of this PR were written by Gemini 3, I reviewed each change manually and made some changes.

Summary

Fixes #8145, hex literals like 0x20_0000_0000_0000 or 0x30_0000_0000_0000 would previously be incorrectly flagged, instead of correctly checking if the provided literal is exactly representable as an f64 it would just check if it's in the safe integer range.
While working on this I also noticed a problem that affects another lint rule noConstantMathMinMaxClamp where large hex literals above 2^63 - 1 would never trigger the error because as_number() internally tried to parse into an i64 which is incorrect.

Test Plan

There are existing tests along with some newly added ones.

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2025

🦋 Changeset detected

Latest commit: 96e6537

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter A-Parser Area: parser L-JavaScript Language: JavaScript and super languages labels Nov 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

Replaces parsing-based overflow/precision checks for non-decimal numeric literals with a bitwise digit analysis in the correctness/noPrecisionLoss lint rule (computes bits-per-digit and checks highest/lowest set-bit positions for overflow or precision loss). Changes non-decimal number parsing in parse_js_number to a manual accumulator path that produces f64 for large hex/binary/octal literals. Adds and expands tests for noPrecisionLoss and noConstantMathMinMaxClamp covering large hex, binary, octal and decimal literals (including Infinity/overflow cases). Adds patch release notes. No public API signature changes.

Suggested reviewers

  • dyc3
  • ematipico

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarises the main change: fixing the noPrecisionLoss rule to correctly handle large hex literals.
Description check ✅ Passed The description clearly explains the fix for issue #8145 and the related bug in noConstantMathMinMaxClamp, directly relating to the changeset.
Linked Issues check ✅ Passed The changes successfully implement all objectives from issue #8145: replacing safe-integer-range checks with f64 representability checks in noPrecisionLoss, fixing as_number() parsing for hex literals, and adding comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing noPrecisionLoss and noConstantMathMinMaxClamp rules; modifications to number parsing, validation logic, and test cases are all related to the stated objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8647e08 and 96e6537.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/correctness/no_precision_loss.rs (1 hunks)
🔇 Additional comments (2)
crates/biome_js_analyze/src/lint/correctness/no_precision_loss.rs (2)

119-128: Safe radix handling—reasonable trade-off.

The default case returns false rather than panicking, which is safer given past review feedback about avoiding unreachable!(). The comment correctly notes that split_into_radix_and_number guarantees radix ∈ {2, 8, 16}, so this fallback should never execute in practice.


130-182: Test coverage verified—all edge cases included.

The test suite comprehensively covers 2^53 (precision limit), 2^100+1 (precision loss), 2^1024 (overflow), and numeric separators across hex, binary, and octal. Diagnostics properly reflect IEEE 754 behaviour (precision truncation and infinity).


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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/invalid.js (1)

36-42: Invalid repro literals exercise the new edge conditions well

The added cases for 2^53+1, 2^100+1 and the 2^1024 overflow nicely mirror the new valid tests and directly cover the precision‑loss and overflow branches in the updated rule. Only minor nit: 0x20000000000001 now appears twice in this file; not wrong, just a bit redundant if you ever want to trim the fixtures.

crates/biome_js_analyze/src/lint/correctness/no_precision_loss.rs (1)

120-177: Bit‑span check for base 2/8/16 looks correct and matches the tests

The MSB/LSB tracking plus span > 53 and msb >= 1024 conditions give a precise characterisation of when an integer literal stops being exactly representable as an f64 or overflows, and the new tests cover those branches well. The only tiny nits (purely optional): the explicit '_' skip is redundant given split_into_radix_and_number already removes underscores, and you could early‑return once span exceeds 53 or msb hits 1024 to avoid scanning the rest of very long literals—but that’s micro‑optimisation territory.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 575129a and 2e11f89.

⛔ Files ignored due to path filters (3)
  • crates/biome_js_analyze/tests/specs/correctness/noConstantMathMinMaxClamp/invalid_large_hex.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/valid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (6)
  • .changeset/odd-kings-obey.md (1 hunks)
  • crates/biome_js_analyze/src/lint/correctness/no_precision_loss.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noConstantMathMinMaxClamp/invalid_large_hex.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/invalid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/valid.js (1 hunks)
  • crates/biome_js_syntax/src/numbers.rs (2 hunks)
🔇 Additional comments (5)
.changeset/odd-kings-obey.md (1)

1-7: Changeset entry looks good.

The format is correct, references are accurate, and the description clearly conveys what was fixed and which rules are affected. No issues here.

crates/biome_js_syntax/src/numbers.rs (2)

40-46: Non‑decimal accumulator looks correct and avoids i64 limits

The value = value * base + digit path is a clean way to parse large binary/octal/hex literals directly as f64, and it lines up with the new tests around 2^53+1 and overflow. No issues spotted here.


83-89: Good boundary coverage for hex literals

The new tests around 0x20000000000001 and the huge 2^1024 literal nicely pin down both precision‑loss and overflow behaviour for hex parsing. Comment + expected values match what JS actually does at runtime.

crates/biome_js_analyze/tests/specs/correctness/noConstantMathMinMaxClamp/invalid_large_hex.js (1)

1-2: Nice regression test for large hex in Math.min/Math.max

This captures the previous i64 overflow edge case well and should keep noConstantMathMinMaxClamp honest for very large hex literals.

crates/biome_js_analyze/tests/specs/correctness/noPrecisionLoss/valid.js (1)

79-85: New “valid” big literals match the exact‑representable set

Marking 2^53, 2^100 and the 2^1023 hex literal as valid is consistent with the updated “exact f64” notion of precision loss and the linked issue. Tests look spot on.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 19, 2025

CodSpeed Performance Report

Merging #8172 will improve performances by 6.65%

Comparing JeremyMoeglich:main (96e6537) with main (79adaea)1

Summary

⚡ 1 improvement
✅ 57 untouched
⏩ 95 skipped2

Benchmarks breakdown

Benchmark BASE HEAD Change
js_analyzer[parser_13571644119461115204.ts] 100.4 ms 94.1 ms +6.65%

Footnotes

  1. No successful run was found on main (575129a) during the generation of this report, so 79adaea was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 95 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great 💯

@JeremyMoeglich JeremyMoeglich requested a review from dyc3 November 20, 2025 17:10
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff!

@dyc3 dyc3 added this pull request to the merge queue Nov 22, 2025
Merged via the queue into biomejs:main with commit de98933 Nov 22, 2025
19 checks passed
@github-actions github-actions bot mentioned this pull request Nov 21, 2025
ryan-m-walker pushed a commit to ryan-m-walker/biome that referenced this pull request Nov 23, 2025
@github-actions github-actions bot mentioned this pull request Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter A-Parser Area: parser L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 correctness/noPrecisionLoss incorrectly flags hex literals above or equal to 2^53 even if valid

3 participants