Skip to content

BE-525: HashQL: Remove implicit type-widening from Integer operations, and make comparison size aware#8693

Open
indietyp wants to merge 3 commits intobm/be-515-hashql-remove-offset-0-materialization-fence-from-generatedfrom
bm/be-525-hashql-remove-implicit-type-widening-into-num-for-int
Open

BE-525: HashQL: Remove implicit type-widening from Integer operations, and make comparison size aware#8693
indietyp wants to merge 3 commits intobm/be-515-hashql-remove-offset-0-materialization-fence-from-generatedfrom
bm/be-525-hashql-remove-implicit-type-widening-into-num-for-int

Conversation

@indietyp
Copy link
Copy Markdown
Member

@indietyp indietyp commented May 4, 2026

🌟 What is the purpose of this PR?

Integer arithmetic in the MIR interpreter previously silently promoted overflowing i128 operations to floating-point results via a Numeric enum. This was semantically incorrect: the language specifies arbitrary-precision integers, and silently widening to f64 loses precision and masks errors. This PR replaces that silent promotion with explicit overflow detection, surfacing a user-facing IntegerOverflow runtime error when addition, subtraction, or negation exceeds the 128-bit range supported by the interpreter.

As a side effect, the Int type's equality, ordering, and hashing semantics are corrected so that booleans (1-bit integers) are treated as a distinct type from integers (128-bit), rather than comparing equal to numeric integers with the same value. This restores type-level correctness for Bool vs Int comparisons throughout the value layer.

🔍 What does this change?

  • Adds a RuntimeError::IntegerOverflow variant with an operation field, and a corresponding integer_overflow diagnostic emitted under the RuntimeLimit category with a note that the interpreter supports up to 128-bit integers.
  • Replaces the Neg, Add<Int>, and Sub<Int> operator impls on Int (which returned Numeric and silently promoted to f64 on overflow) with checked_neg, checked_add, and checked_sub methods that return Option<Int>.
  • Removes the Numeric enum entirely, along with the From<Numeric> for Value conversion and all associated forwarding impls.
  • Updates the binary and unary operation dispatch in the interpreter runtime to use the new checked methods and return RuntimeError::IntegerOverflow on None.
  • Fixes Int's PartialEq, Ord, and Hash implementations to include the size field, so that Int::from(true) (1-bit) and Int::from(1_i32) (128-bit) are no longer considered equal.
  • Fixes PartialEq<Int> for Num, PartialOrd<Int> for Num, and their reverses to return false/None when the Int is a boolean, since booleans are not a subtype of Number.
  • Updates Value::Ord to guard the cross-type Integer/Number ordering arms with !this.is_bool() / !other.is_bool().
  • Updates InstSimplifyVisitor::eval_un_op to return Option<Int> and skip constant folding for negation of i128::MIN.
  • Adds interpreter tests for addition, subtraction, and negation overflow, and an inst_simplify test confirming that neg(i128::MIN) is not folded.
  • Updates all unit tests in int.rs and mod.rs to reflect the corrected bool/int distinction.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

🛡 What tests cover this?

  • New interpreter tests: integer_add_overflow, integer_sub_overflow, integer_neg_overflow — each confirms a RuntimeLimit diagnostic is produced.
  • New inst_simplify test: const_fold_neg_overflow — confirms that negation of i128::MIN is left unfolded.
  • Updated unit tests in Int and Value covering corrected equality, ordering, hashing, and cross-type Num/Int comparisons.

❓ How to test this?

  1. Run cargo test -p hashql-mir and confirm all tests pass.
  2. Verify that the new snapshot const_fold_neg_overflow.snap matches the expected unfold output.
  3. Confirm that expressions producing integer overflow at runtime emit a diagnostic with category RuntimeLimit and a message referencing the 128-bit limit.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment May 8, 2026 8:46am
petrinaut Ready Ready Preview May 8, 2026 8:46am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview May 8, 2026 8:46am

@vercel vercel Bot temporarily deployed to Preview – petrinaut May 4, 2026 10:33 Inactive
@cursor
Copy link
Copy Markdown

cursor Bot commented May 4, 2026

PR Summary

Medium Risk
Changes core interpreter numeric semantics: integer add/sub/neg now error on i128 overflow instead of silently widening, and Bool vs Int equality/ordering/hashing is no longer value-only. This can alter runtime results and constant-folding output for existing programs relying on the old behavior.

Overview
Prevents silent type-widening from integer arithmetic by introducing a user-facing RuntimeError::IntegerOverflow diagnostic and making +, -, and unary neg on Int use checked operations that fail when results exceed the interpreter’s i128 range.

Updates Int, Num, and Value comparison/ordering/hashing semantics to be size-aware, treating 1-bit booleans as distinct from 128-bit integers (and disallowing bool↔number equality/ordering), and adjusts constant-folding (inst_simplify) to use these semantics and to skip folding negation overflow. Adds targeted runtime and pass tests/snapshots for overflow and bool-vs-int constant folding.

Reviewed by Cursor Bugbot for commit 1d64eff. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team area/tests New or updated tests labels May 4, 2026
Copy link
Copy Markdown
Member Author

indietyp commented May 4, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 4, 2026

🤖 Augment PR Summary

Summary: This PR fixes HashQL MIR interpreter integer semantics by removing implicit type-widening on overflow and making comparisons size-aware.

Changes:

  • Adds RuntimeError::IntegerOverflow plus a new RuntimeLimit diagnostic for i128-range overflows.
  • Updates runtime dispatch for Add/Sub/Neg on Int to use checked arithmetic and surface overflow as an explicit runtime error.
  • Removes the Numeric enum and associated conversion plumbing that previously promoted overflowing Int operations into f64.
  • Makes Int equality/ordering/hashing include the size field so Bool (1-bit) and Int (128-bit) are distinct at the value layer.
  • Adjusts NumInt cross-type comparison to treat booleans as neither equal nor orderable with Num.
  • Updates Value::Ord to only apply numeric ordering between Integer/Number for non-bool integers.
  • Updates constant folding to avoid folding neg(i128::MIN) and adds interpreter + inst_simplify regression tests/snapshots for overflow cases.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

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

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread libs/@local/hashql/mir/src/interpret/value/int.rs
@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

❌ Patch coverage is 97.42268% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.24%. Comparing base (58bba8c) to head (b87ca3d).

Files with missing lines Patch % Lines
libs/@local/hashql/mir/src/interpret/value/mod.rs 83.33% 1 Missing and 2 partials ⚠️
libs/@local/hashql/mir/src/interpret/error.rs 90.90% 1 Missing ⚠️
...hashql/mir/src/pass/transform/inst_simplify/mod.rs 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                                            Coverage Diff                                             @@
##           bm/be-515-hashql-remove-offset-0-materialization-fence-from-generated    #8693       +/-   ##
==========================================================================================================
+ Coverage                                                                  53.92%   66.24%   +12.32%     
==========================================================================================================
  Files                                                                        778      934      +156     
  Lines                                                                      57232    84770    +27538     
  Branches                                                                    3839     4465      +626     
==========================================================================================================
+ Hits                                                                       30863    56160    +25297     
- Misses                                                                     26041    28062     +2021     
- Partials                                                                     328      548      +220     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.41% <ø> (ø)
apps.hash-api 0.00% <ø> (ø)
local.hash-backend-utils 0.00% <ø> (ø)
local.hash-graph-sdk 9.63% <ø> (ø)
local.hash-isomorphic-utils 0.00% <ø> (ø)
rust.hash-graph-api 2.52% <ø> (ø)
rust.hashql-compiletest 28.26% <ø> (ø)
rust.hashql-eval 79.70% <ø> (ø)
rust.hashql-mir 91.86% <97.42%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 4, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks
⏩ 56 skipped benchmarks1


Comparing bm/be-525-hashql-remove-implicit-type-widening-into-num-for-int (b87ca3d) with bm/be-515-hashql-remove-offset-0-materialization-fence-from-generated (9db238d)2

Open in CodSpeed

Footnotes

  1. 56 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.

  2. No successful run was found on bm/be-515-hashql-remove-offset-0-materialization-fence-from-generated (58bba8c) during the generation of this report, so 161d40f was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@vercel vercel Bot temporarily deployed to Preview – petrinaut May 4, 2026 10:39 Inactive
@indietyp indietyp changed the title BE-525: Remove implicit type-widening from Integer operations, and make comparison size aware BE-525: HashQL: Remove implicit type-widening from Integer operations, and make comparison size aware May 4, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 07de63c. Configure here.

Comment thread libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs
@indietyp indietyp force-pushed the bm/be-525-hashql-remove-implicit-type-widening-into-num-for-int branch from 07de63c to b87ca3d Compare May 4, 2026 11:34
@indietyp indietyp force-pushed the bm/be-515-hashql-remove-offset-0-materialization-fence-from-generated branch from a0db929 to 58bba8c Compare May 4, 2026 11:34
@indietyp indietyp force-pushed the bm/be-515-hashql-remove-offset-0-materialization-fence-from-generated branch from 58bba8c to 2a89970 Compare May 8, 2026 08:33
@indietyp indietyp force-pushed the bm/be-525-hashql-remove-implicit-type-widening-into-num-for-int branch from b87ca3d to 1d64eff Compare May 8, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

1 participant