Semantic Diff

#8871 Compile integer operations with an identity operand to the operand

1 commit, rendered from its record.

Summary

RangeCommitsChangelogAreasJS output changesFormatsFailed checks
fb7a59bd8313d39098af4659332079695d0a54b9..pr-88711๐Ÿ’… Polishcodegentests1none0

Changelog draft

๐Ÿ’… Polish
  • Compile integer x + 0, 0 + x, x - 0, x * 1, 1 * x and x / 1 to x. #8871

fb7a59bd8313d39098af4659332079695d0a54b9..pr-8871

018a94f20 ยท Cristiano Calcagno ยท Oct 14, 2026 ยท #8871 discussion โ†—

Compile integer operations with an identity operand to the operand

๐Ÿ’… Polishcodegentests

Integer x + 0, 0 + x, x - 0, x * 1, 1 * x and x / 1 compile to x. A ReScript int value is a 32-bit integer in JavaScript, so the | 0 truncation (or << 0 for * 1) that these operations emitted leaves the value unchanged. The JavaScript expression builders in Js_exp_make (int32_add, int32_minus, int32_mul, int32_div) return the other operand when one operand is the literal identity. The dropped operand is a literal, so evaluation of the kept operand is unchanged.

Example ReScript

let addZero = (x: int) => x + 0let subZero = (x: int) => x - 0let mulOne = (x: int) => x * 1let divOne = (x: int) => x / 1
Before JavaScript
function addZero(x) {  return x + 0 | 0;} function subZero(x) {  return x - 0 | 0;} function mulOne(x) {  return (x << 0);} function divOne(x) {  return x / 1 | 0;}
After JavaScript
function addZero(x) {  return x;} function subZero(x) {  return x;} function mulOne(x) {  return x;} function divOne(x) {  return x;}

Source bsc Example.res (CommonJS, to stdout) with bsc built from aa2078e3d (Before) and from this commit (After); function bodies shown, the module header and exports are identical.

๐Ÿ’… Polish- Compile integer x + 0, 0 + x, x - 0, x * 1, 1 * x and x / 1 to x. #8871

Review

No effect
Formats: none
Output
changedinteger + 0, 0 +, - 0, * 1, 1 *, / 1 on a non-literal operand, now the bare operand; in tests/tests/src one existing snapshot changes (gpr_3609_test.mjs, 0 + state._0 | 0 -> state._0) and in the gentype example Docstrings.res.js six + 0 functions drop the addition (a + 0 | 0 -> a), and the stdlib build (make lib) emits no changed JS
Tests
integration tests/tests/src/+ int_identity_ops_test.res+ int_identity_ops_test.mjs~ gpr_3609_test.mjs
gentype~ tests/gentype_tests/typescript-react-example/src/Docstrings.res.js
6 files ยท +124 โˆ’10 ยท changelog 1 ยท codegen 1 ยท tests 4
Achanges/int-identity-ops.polish.md+1โˆ’0
Mcompiler/core/js_exp_make.ml+15โˆ’3
Mtests/gentype_tests/typescript-react-example/src/Docstrings.res.js+6โˆ’6
Mtests/tests/src/gpr_3609_test.mjs+1โˆ’1
Atests/tests/src/int_identity_ops_test.mjs+69โˆ’0
Atests/tests/src/int_identity_ops_test.res+32โˆ’0
with Claude Opus 5.5