Skip to content

Visit an arrow's argument types without a closure - #9286

Open
JonoPrest wants to merge 1 commit into
masterfrom
jono/iter-arg-types
Open

JonoPrest wants to merge 1 commit into
masterfrom
jono/iter-arg-types

Conversation

@JonoPrest

Copy link
Copy Markdown
Contributor

Btype.iter_type_expr visited the argument types of a Tarrow with List.iter (fun {typ} -> f typ) params, which allocates a closure each time it reaches an arrow type. Many type walks go through it (copying, marking, levels, occur checks). The arguments are now visited by a small recursive function that takes f, in the same order.

Measurement (compilerBenchmarks.js, allocated words) Change
Total -0.22%
Files compiled one by one -0.20%
Builds of tests/tests -0.24%
stress/NestedClosures.res -0.89%
552-module app, clean build, worker words (1 domain) -0.18%

Build outputs (JS, .cmi, .cmj, .ast) are byte-identical on three real-world projects and their dependencies at default and one domain.

Checklist

  • Added a changelog fragment (see changes/README.md), or no release notes are needed and a maintainer should apply changelog:skip.
  • Added tests for the fix or feature.
  • Gave every commit a description below its subject, saying why it is made (see "Commit messages" in CONTRIBUTING.md).
  • Signed off every commit for the DCO (git commit -s).

@JonoPrest

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T15:54:59.003204Z 4a9f29b Manual request
ℹ️ 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.

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Changelog

💅 Polish

  • Walk the parameters of a function type without allocating a closure, so the compiler allocates about 0.2% less.

Semantic Diff

1 commit · Full page

Visit an arrow's argument types without a closure

f88ccc9 · JonoPrest · Nov 09, 2026, 14:40 UTC

Why

iter_type_expr visited the argument types of a Tarrow with List.iter (fun {typ} -> f typ), which allocates a closure each time it reaches an arrow type. Many walks over types go through it (copying, marking, levels, occur checks), and function types are common.

The arguments are now visited by a recursive function that takes f. The order of the visits is unchanged.

Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -0.22% in total (-0.20% for the files compiled one by one, -0.24% in the builds of tests/tests), stress/NestedClosures.res -0.89%. On a 552 module React app (clean build, one domain) the build allocates 0.18% fewer words.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 4a9f29bbd2

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

✅ Compiler benchmarks

Allocated words

In total: 683,548,718 → 682,021,379 (-0.22%).

Benchmark Base Head Change
stress/NestedClosures.res 11,543,225 11,440,637 -0.89%
stress/LetRec.res 34,771,631 34,491,623 -0.81%
packages/@rescript/runtime/JsxEvent.res 1,104,000 1,097,139 -0.62%
stress/InlineChain.res 3,727,128 3,707,884 -0.52%
packages/@rescript/runtime/JsxDOM.res 2,832,022 2,819,062 -0.46%
packages/@rescript/runtime/Stdlib_TypedArray.res 795,026 791,426 -0.45%
packages/@rescript/belt/src/Belt_Array.res 2,349,207 2,339,386 -0.42%
packages/@rescript/runtime/Stdlib_Lazy.res 231,686 230,790 -0.39%
packages/@rescript/runtime/Primitive_object.res 1,240,833 1,236,169 -0.38%
packages/@rescript/runtime/Pervasives.res 242,003 241,103 -0.37%
164 more changes
Benchmark Base Head Change
packages/@rescript/belt/src/Belt_SortArray.res 1,563,066 1,557,291 -0.37%
packages/@rescript/runtime/Stdlib_Array.res 1,361,912 1,357,076 -0.36%
build/shared-edit 75,190,358 74,933,857 -0.34%
packages/@rescript/belt/src/Belt_SortArrayInt.res 1,448,282 1,443,512 -0.33%
packages/@rescript/belt/src/Belt_SortArrayString.res 1,450,080 1,445,308 -0.33%
packages/@rescript/runtime/Primitive_option.res 315,661 314,633 -0.33%
packages/@rescript/belt/src/Belt_Range.res 300,432 299,480 -0.32%
packages/@rescript/runtime/Stdlib_JsError.res 235,345 234,633 -0.30%
packages/@rescript/runtime/Stdlib_Math.res 332,110 331,166 -0.28%
packages/@rescript/runtime/Primitive_hash.res 1,022,797 1,019,959 -0.28%
packages/@rescript/runtime/Stdlib_List.res 2,903,131 2,895,335 -0.27%
packages/@rescript/belt/src/Belt_List.res 3,451,343 3,442,079 -0.27%
packages/@rescript/runtime/Stdlib_AsyncIterator.res 312,594 311,758 -0.27%
packages/@rescript/runtime/Primitive_array.res 201,292 200,760 -0.26%
packages/@rescript/runtime/Stdlib_JsExn.res 177,282 176,814 -0.26%
packages/@rescript/belt/src/Belt_HashMap.res 1,362,983 1,359,431 -0.26%
packages/@rescript/runtime/Stdlib_Dict.res 328,030 327,214 -0.25%
packages/@rescript/runtime/Stdlib_Iterator.res 243,369 242,773 -0.24%
packages/@rescript/belt/src/Belt_Array.resi 672,434 670,814 -0.24%
build/leaf-edit 13,851,821 13,818,817 -0.24%
packages/@rescript/belt/src/Belt_List.resi 791,279 789,419 -0.24%
packages/@rescript/belt/src/Belt_MutableSetString.resi 267,242 266,618 -0.23%
packages/@rescript/belt/src/Belt_MutableSetInt.resi 267,359 266,735 -0.23%
packages/@rescript/belt/src/Belt_internalBuckets.res 1,076,130 1,073,624 -0.23%
packages/@rescript/runtime/Primitive_module.res 356,839 356,015 -0.23%
packages/@rescript/belt/src/Belt_Id.res 296,203 295,523 -0.23%
packages/@rescript/belt/src/Belt_MutableSet.res 2,121,669 2,116,801 -0.23%
packages/@rescript/belt/src/Belt_internalAVLset.res 3,174,101 3,166,941 -0.23%
packages/@rescript/runtime/Stdlib_List.resi 418,354 417,418 -0.22%
packages/@rescript/belt/src/Belt_MapString.resi 399,342 398,454 -0.22%
packages/@rescript/belt/src/Belt_MapInt.resi 399,385 398,497 -0.22%
packages/@rescript/belt/src/Belt_Map.res 1,073,930 1,071,550 -0.22%
packages/@rescript/belt/src/Belt_SetString.resi 262,017 261,441 -0.22%
packages/@rescript/belt/src/Belt_SetInt.resi 262,144 261,568 -0.22%
packages/@rescript/belt/src/Belt_HashSet.res 1,092,814 1,090,424 -0.22%
packages/@rescript/runtime/Stdlib_Nullable.res 347,588 346,828 -0.22%
build/no-op 9,848,374 9,826,889 -0.22%
packages/@rescript/belt/src/Belt_MutableMapString.resi 320,569 319,873 -0.22%
packages/@rescript/belt/src/Belt_MutableMapInt.resi 320,687 319,991 -0.22%
packages/@rescript/belt/src/Belt_MutableSetInt.res 1,830,853 1,826,881 -0.22%
packages/@rescript/belt/src/Belt_MutableSetString.res 1,832,096 1,828,124 -0.22%
packages/@rescript/runtime/Stdlib_String.res 514,012 512,900 -0.22%
packages/@rescript/belt/src/Belt_HashSetString.res 932,602 930,586 -0.22%
packages/@rescript/belt/src/Belt_HashSetInt.res 932,283 930,271 -0.22%
packages/@rescript/runtime/Stdlib_Int.res 470,160 469,148 -0.22%
build/clean 246,756,517 246,227,420 -0.21%
packages/@rescript/runtime/Stdlib_Temporal_PlainDateTime.res 441,498 440,554 -0.21%
packages/@rescript/belt/src/Belt_internalSetBuckets.res 759,864 758,260 -0.21%
stress/RefsInLoop.res 17,141,783 17,105,779 -0.21%
packages/@rescript/runtime/Stdlib_Date.res 558,990 557,818 -0.21%
packages/@rescript/runtime/Stdlib_Int8Array.res 344,396 343,684 -0.21%
packages/@rescript/runtime/Stdlib_Uint8Array.res 344,411 343,699 -0.21%
packages/@rescript/runtime/Stdlib_Float32Array.res 344,514 343,802 -0.21%
packages/@rescript/runtime/Stdlib_Float64Array.res 344,514 343,802 -0.21%
packages/@rescript/runtime/Stdlib_Int16Array.res 344,543 343,831 -0.21%
packages/@rescript/runtime/Stdlib_Int32Array.res 344,545 343,833 -0.21%
packages/@rescript/runtime/Stdlib_Uint16Array.res 344,550 343,838 -0.21%
packages/@rescript/runtime/Stdlib_Uint32Array.res 344,550 343,838 -0.21%
packages/@rescript/runtime/Stdlib_BigInt64Array.res 344,576 343,864 -0.21%
packages/@rescript/runtime/Stdlib_BigUint64Array.res 344,650 343,938 -0.21%
packages/@rescript/runtime/Stdlib_Uint8ClampedArray.res 344,926 344,214 -0.21%
packages/@rescript/runtime/Stdlib_Null.res 349,603 348,883 -0.21%
packages/@rescript/runtime/Stdlib_Array.resi 746,634 745,098 -0.21%
packages/@rescript/belt/src/Belt_HashMapInt.res 1,190,629 1,188,183 -0.21%
packages/@rescript/belt/src/Belt_HashMapString.res 1,191,337 1,188,895 -0.20%
packages/@rescript/belt/src/Belt_internalAVLtree.res 3,941,284 3,933,412 -0.20%
packages/@rescript/runtime/Stdlib_Temporal_PlainDate.res 407,039 406,235 -0.20%
packages/@rescript/runtime/Stdlib_Temporal_ZonedDateTime.res 581,114 579,970 -0.20%
packages/@rescript/runtime/Primitive_exceptions.res 207,901 207,493 -0.20%
packages/@rescript/runtime/Primitive_bigint.res 181,841 181,497 -0.19%
packages/@rescript/runtime/Stdlib_Object.res 246,460 246,000 -0.19%
packages/@rescript/runtime/Stdlib_Temporal_Duration.res 377,976 377,272 -0.19%
packages/@rescript/belt/src/Belt_Set.res 932,088 930,364 -0.18%
packages/@rescript/belt/src/Belt_MutableMap.res 1,459,148 1,456,450 -0.18%
packages/@rescript/belt/src/Belt_MutableMapString.res 1,291,746 1,289,394 -0.18%
packages/@rescript/belt/src/Belt_MutableMapInt.res 1,291,463 1,289,113 -0.18%
packages/@rescript/runtime/Primitive_int.res 176,287 175,967 -0.18%
packages/@rescript/runtime/Primitive_string.res 163,632 163,336 -0.18%
packages/@rescript/runtime/Stdlib_AsyncIterableIterator.res 241,203 240,767 -0.18%
packages/@rescript/runtime/Stdlib_Type.res 204,444 204,076 -0.18%
packages/@rescript/runtime/Stdlib_BigInt.res 209,476 209,108 -0.18%
packages/@rescript/runtime/Stdlib_Console.res 377,726 377,066 -0.17%
packages/@rescript/belt/src/Belt_MutableMap.resi 407,490 406,782 -0.17%
packages/@rescript/runtime/Stdlib_Math.resi 332,942 332,366 -0.17%
packages/@rescript/belt/src/Belt_Option.resi 246,170 245,750 -0.17%
packages/@rescript/runtime/Stdlib_Promise.res 371,448 370,820 -0.17%
packages/@rescript/runtime/Stdlib_Ordering.res 154,046 153,786 -0.17%
packages/@rescript/belt/src/Belt_internalSetInt.res 788,501 787,171 -0.17%
packages/@rescript/belt/src/Belt_internalSetString.res 789,694 788,362 -0.17%
packages/@rescript/belt/src/Belt_Option.res 403,611 402,939 -0.17%
packages/@rescript/belt/src/Belt_MapDict.resi 533,107 532,221 -0.17%
packages/@rescript/belt/src/Belt_MapDict.res 1,875,071 1,871,987 -0.16%
packages/@rescript/belt/src/Belt_MapString.res 1,333,987 1,331,797 -0.16%
packages/@rescript/belt/src/Belt_MapInt.res 1,333,449 1,331,265 -0.16%
packages/@rescript/runtime/Stdlib_AsyncGenerator.res 224,175 223,811 -0.16%
packages/@rescript/runtime/Stdlib_Temporal_PlainTime.res 322,879 322,355 -0.16%
packages/@rescript/runtime/Stdlib_IterableIterator.res 186,264 185,964 -0.16%
packages/@rescript/belt/src/Belt_MutableQueue.res 847,634 846,278 -0.16%
packages/@rescript/runtime/Stdlib_Date.resi 624,268 623,272 -0.16%
packages/@rescript/runtime/Stdlib_String.resi 504,688 503,884 -0.16%
packages/@rescript/belt/src/Belt_internalMapInt.res 1,610,677 1,608,157 -0.16%
packages/@rescript/belt/src/Belt_internalMapString.res 1,612,527 1,610,005 -0.16%
packages/@rescript/runtime/Stdlib_Console.resi 422,754 422,094 -0.16%
packages/@rescript/runtime/Stdlib_Temporal_PlainYearMonth.res 387,018 386,414 -0.16%
packages/@rescript/runtime/Primitive_list.res 213,196 212,864 -0.16%
packages/@rescript/runtime/Dom_storage.res 169,942 169,678 -0.16%
packages/@rescript/belt/src/Belt_HashMapString.resi 216,385 216,049 -0.16%
packages/@rescript/belt/src/Belt_HashMapInt.resi 216,500 216,164 -0.16%
packages/@rescript/belt/src/Belt_MutableQueue.resi 209,492 209,168 -0.15%
packages/@rescript/belt/src/Belt_MutableSet.resi 407,088 406,464 -0.15%
packages/@rescript/belt/src/Belt_Map.resi 597,409 596,500 -0.15%
packages/@rescript/runtime/Stdlib_Pair.res 168,525 168,269 -0.15%
packages/@rescript/belt/src/Belt_SetInt.res 1,413,088 1,410,944 -0.15%
packages/@rescript/belt/src/Belt_SetString.res 1,413,817 1,411,673 -0.15%
packages/@rescript/runtime/Stdlib_IteratorObject.res 264,450 264,050 -0.15%
packages/@rescript/runtime/Stdlib_RegExp.res 164,130 163,882 -0.15%
packages/@rescript/belt/src/Belt_SortArray.resi 256,541 256,157 -0.15%
packages/@rescript/runtime/Stdlib_JSON.res 302,239 301,787 -0.15%
packages/@rescript/belt/src/Belt_internalAVLset.resi 371,093 370,541 -0.15%
packages/@rescript/runtime/Stdlib_BigInt.resi 187,480 187,204 -0.15%
packages/@rescript/runtime/Stdlib_Global.res 141,938 141,730 -0.15%
packages/@rescript/belt/src/Belt_SetDict.res 1,634,169 1,631,785 -0.15%
packages/@rescript/belt/src/Belt_internalAVLtree.resi 480,017 479,321 -0.14%
packages/@rescript/runtime/Stdlib_Set.res 214,234 213,926 -0.14%
packages/@rescript/runtime/Stdlib_Temporal_Instant.res 310,488 310,044 -0.14%
packages/@rescript/belt/src/Belt_HashSetString.resi 176,274 176,022 -0.14%
packages/@rescript/belt/src/Belt_HashSetInt.resi 176,387 176,135 -0.14%
packages/@rescript/runtime/Stdlib_Float.res 221,240 220,924 -0.14%
packages/@rescript/runtime/Stdlib_JsError.resi 186,162 185,898 -0.14%
packages/@rescript/runtime/Primitive_float.res 149,645 149,433 -0.14%
packages/@rescript/belt/src/Belt_MutableStack.res 413,965 413,385 -0.14%
packages/@rescript/runtime/Stdlib_Intl_Locale.res 199,881 199,601 -0.14%
packages/@rescript/runtime/Stdlib_DataView.res 231,761 231,437 -0.14%
packages/@rescript/belt/src/Belt_Set.resi 447,971 447,347 -0.14%
packages/@rescript/belt/src/Belt_SetDict.resi 414,166 413,590 -0.14%
packages/@rescript/runtime/Jsx.res 122,098 121,930 -0.14%
packages/@rescript/runtime/Stdlib_Result.resi 305,424 305,004 -0.14%
packages/@rescript/belt/src/Belt_Range.resi 177,268 177,028 -0.14%
packages/@rescript/runtime/Stdlib_Generator.res 209,917 209,633 -0.14%
packages/@rescript/runtime/Stdlib_Option.resi 241,144 240,820 -0.13%
packages/@rescript/runtime/Stdlib_Map.res 210,049 209,777 -0.13%
packages/@rescript/runtime/Stdlib_IteratorObject.resi 241,227 240,915 -0.13%
packages/@rescript/runtime/Stdlib_Dict.resi 244,911 244,599 -0.13%
packages/@rescript/runtime/Stdlib_Global.resi 156,337 156,145 -0.12%
packages/@rescript/runtime/Stdlib_JSON.resi 239,282 238,990 -0.12%
packages/@rescript/runtime/Primitive_object_extern.res 114,734 114,594 -0.12%
packages/@rescript/runtime/Stdlib_Int.resi 207,249 206,997 -0.12%
packages/@rescript/belt/src/Belt_Result.resi 247,960 247,660 -0.12%
packages/@rescript/belt/src/Belt_MutableStack.resi 170,428 170,224 -0.12%
packages/@rescript/runtime/Stdlib_Temporal_PlainMonthDay.res 270,970 270,646 -0.12%
packages/@rescript/runtime/Stdlib_DataView.resi 271,148 270,824 -0.12%
packages/@rescript/runtime/Stdlib_Nullable.resi 204,247 204,007 -0.12%
packages/@rescript/runtime/Stdlib_Promise.resi 376,507 376,067 -0.12%
packages/@rescript/runtime/Stdlib_Null.resi 208,735 208,495 -0.11%
packages/@rescript/runtime/Stdlib_RegExp.resi 189,282 189,066 -0.11%
packages/@rescript/runtime/Stdlib_Set.resi 232,564 232,300 -0.11%
packages/@rescript/belt/src/Belt_HashSet.resi 226,843 226,591 -0.11%
packages/@rescript/belt/src/Belt_HashMap.resi 303,382 303,046 -0.11%
packages/@rescript/belt/src/Belt_Result.res 439,339 438,879 -0.10%
packages/@rescript/runtime/Stdlib_Float.resi 195,361 195,157 -0.10%
packages/@rescript/belt/src/Belt_internalBucketsType.res 299,013 298,705 -0.10%
packages/@rescript/runtime/Stdlib_Map.resi 221,621 221,393 -0.10%
packages/@rescript/belt/src/Belt_Id.resi 261,547 261,283 -0.10%
packages/@rescript/runtime/Dom_storage2.res 119,942 119,822 -0.10%

Instructions

In total: 9,664,672,297 → 9,665,362,885 (+0.01%).

Benchmark Base Head Change
stress/ObjectFields.res 950,039,985 952,026,043 +0.21%

Output size

In total: 25,569,598 → 25,569,606 (±0.00%).

None of the 13 benchmarks changed by 0.1% or more.

Pull request f88ccc9 compared with base b82d944 in this run.

@codecov

codecov Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.92%. Comparing base (70da3d1) to head (c63c67a).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9286   +/-   ##
=======================================
  Coverage   81.92%   81.92%           
=======================================
  Files         456      456           
  Lines       65464    65466    +2     
=======================================
+ Hits        53631    53633    +2     
  Misses      11833    11833           
Files with missing lines Coverage Δ
compiler/ml/btype.ml 90.42% <100.00%> (+0.05%) ⬆️
🚀 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.

@pkg-pr-new

pkg-pr-new Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@9286

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@9286

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@9286

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@9286

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@9286

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@9286

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@9286

commit: c63c67a

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

@JonoPrest
JonoPrest marked this pull request as ready for review November 9, 2026 16:08
@JonoPrest
JonoPrest requested a review from cknitt November 9, 2026 16:08
@JonoPrest
JonoPrest force-pushed the jono/iter-arg-types branch from 4a9f29b to f88ccc9 Compare November 9, 2026 16:48
Why:
    `iter_type_expr` visited the argument types of a `Tarrow` with
    `List.iter (fun {typ} -> f typ)`, which allocates a closure each time
    it reaches an arrow type. Many walks over types go through it
    (copying, marking, levels, occur checks), and function types are
    common.

The arguments are now visited by a recursive function that takes `f`.
The order of the visits is unchanged.

Measured with scripts/compilerBenchmarks.js against the previous commit:
allocated words -0.22% in total (-0.20% for the files compiled one by
one, -0.24% in the builds of tests/tests), stress/NestedClosures.res
-0.89%. On a 552 module React app (clean build, one domain) the build
allocates 0.18% fewer words.

Signed-off-by: Jono Prest <[email protected]>
@JonoPrest
JonoPrest force-pushed the jono/iter-arg-types branch from f88ccc9 to c63c67a Compare November 9, 2026 22:04
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

✅ Compiler benchmarks

Allocated words

In total: 683,547,198 → 682,017,787 (-0.22%).

Benchmark Base Head Change
stress/NestedClosures.res 11,543,225 11,440,637 -0.89%
stress/LetRec.res 34,771,631 34,491,623 -0.81%
packages/@rescript/runtime/JsxEvent.res 1,104,000 1,097,139 -0.62%
stress/InlineChain.res 3,727,128 3,707,884 -0.52%
packages/@rescript/runtime/JsxDOM.res 2,832,022 2,819,062 -0.46%
packages/@rescript/runtime/Stdlib_TypedArray.res 795,026 791,426 -0.45%
packages/@rescript/belt/src/Belt_Array.res 2,349,207 2,339,386 -0.42%
packages/@rescript/runtime/Stdlib_Lazy.res 231,686 230,790 -0.39%
packages/@rescript/runtime/Primitive_object.res 1,240,833 1,236,169 -0.38%
packages/@rescript/runtime/Pervasives.res 242,003 241,103 -0.37%
164 more changes
Benchmark Base Head Change
packages/@rescript/belt/src/Belt_SortArray.res 1,563,066 1,557,291 -0.37%
packages/@rescript/runtime/Stdlib_Array.res 1,361,912 1,357,076 -0.36%
build/shared-edit 75,189,956 74,932,279 -0.34%
packages/@rescript/belt/src/Belt_SortArrayInt.res 1,448,282 1,443,512 -0.33%
packages/@rescript/belt/src/Belt_SortArrayString.res 1,450,080 1,445,308 -0.33%
packages/@rescript/runtime/Primitive_option.res 315,661 314,633 -0.33%
packages/@rescript/belt/src/Belt_Range.res 300,432 299,480 -0.32%
packages/@rescript/runtime/Stdlib_JsError.res 235,345 234,633 -0.30%
packages/@rescript/runtime/Stdlib_Math.res 332,110 331,166 -0.28%
packages/@rescript/runtime/Primitive_hash.res 1,022,797 1,019,959 -0.28%
packages/@rescript/runtime/Stdlib_List.res 2,903,131 2,895,335 -0.27%
packages/@rescript/belt/src/Belt_List.res 3,451,343 3,442,079 -0.27%
packages/@rescript/runtime/Stdlib_AsyncIterator.res 312,594 311,758 -0.27%
packages/@rescript/runtime/Primitive_array.res 201,292 200,760 -0.26%
packages/@rescript/runtime/Stdlib_JsExn.res 177,282 176,814 -0.26%
packages/@rescript/belt/src/Belt_HashMap.res 1,362,983 1,359,431 -0.26%
packages/@rescript/runtime/Stdlib_Dict.res 328,030 327,214 -0.25%
packages/@rescript/runtime/Stdlib_Iterator.res 243,369 242,773 -0.24%
packages/@rescript/belt/src/Belt_Array.resi 672,434 670,814 -0.24%
build/leaf-edit 13,851,784 13,818,875 -0.24%
packages/@rescript/belt/src/Belt_List.resi 791,279 789,419 -0.24%
packages/@rescript/belt/src/Belt_MutableSetString.resi 267,242 266,618 -0.23%
packages/@rescript/belt/src/Belt_MutableSetInt.resi 267,359 266,735 -0.23%
packages/@rescript/belt/src/Belt_internalBuckets.res 1,076,130 1,073,624 -0.23%
packages/@rescript/runtime/Primitive_module.res 356,839 356,015 -0.23%
packages/@rescript/belt/src/Belt_Id.res 296,203 295,523 -0.23%
packages/@rescript/belt/src/Belt_MutableSet.res 2,121,669 2,116,801 -0.23%
packages/@rescript/belt/src/Belt_internalAVLset.res 3,174,101 3,166,941 -0.23%
packages/@rescript/runtime/Stdlib_List.resi 418,354 417,418 -0.22%
packages/@rescript/belt/src/Belt_MapString.resi 399,342 398,454 -0.22%
packages/@rescript/belt/src/Belt_MapInt.resi 399,385 398,497 -0.22%
packages/@rescript/belt/src/Belt_Map.res 1,073,930 1,071,550 -0.22%
packages/@rescript/belt/src/Belt_SetString.resi 262,017 261,441 -0.22%
packages/@rescript/belt/src/Belt_SetInt.resi 262,144 261,568 -0.22%
packages/@rescript/belt/src/Belt_HashSet.res 1,092,814 1,090,424 -0.22%
packages/@rescript/runtime/Stdlib_Nullable.res 347,588 346,828 -0.22%
build/no-op 9,848,335 9,826,852 -0.22%
packages/@rescript/belt/src/Belt_MutableMapString.resi 320,569 319,873 -0.22%
packages/@rescript/belt/src/Belt_MutableMapInt.resi 320,687 319,991 -0.22%
packages/@rescript/belt/src/Belt_MutableSetInt.res 1,830,853 1,826,881 -0.22%
packages/@rescript/belt/src/Belt_MutableSetString.res 1,832,096 1,828,124 -0.22%
packages/@rescript/runtime/Stdlib_String.res 514,012 512,900 -0.22%
packages/@rescript/belt/src/Belt_HashSetString.res 932,602 930,586 -0.22%
packages/@rescript/belt/src/Belt_HashSetInt.res 932,283 930,271 -0.22%
packages/@rescript/runtime/Stdlib_Int.res 470,160 469,148 -0.22%
build/clean 246,755,475 246,225,385 -0.21%
packages/@rescript/runtime/Stdlib_Temporal_PlainDateTime.res 441,498 440,554 -0.21%
packages/@rescript/belt/src/Belt_internalSetBuckets.res 759,864 758,260 -0.21%
stress/RefsInLoop.res 17,141,783 17,105,779 -0.21%
packages/@rescript/runtime/Stdlib_Date.res 558,990 557,818 -0.21%
packages/@rescript/runtime/Stdlib_Int8Array.res 344,396 343,684 -0.21%
packages/@rescript/runtime/Stdlib_Uint8Array.res 344,411 343,699 -0.21%
packages/@rescript/runtime/Stdlib_Float32Array.res 344,514 343,802 -0.21%
packages/@rescript/runtime/Stdlib_Float64Array.res 344,514 343,802 -0.21%
packages/@rescript/runtime/Stdlib_Int16Array.res 344,543 343,831 -0.21%
packages/@rescript/runtime/Stdlib_Int32Array.res 344,545 343,833 -0.21%
packages/@rescript/runtime/Stdlib_Uint16Array.res 344,550 343,838 -0.21%
packages/@rescript/runtime/Stdlib_Uint32Array.res 344,550 343,838 -0.21%
packages/@rescript/runtime/Stdlib_BigInt64Array.res 344,576 343,864 -0.21%
packages/@rescript/runtime/Stdlib_BigUint64Array.res 344,650 343,938 -0.21%
packages/@rescript/runtime/Stdlib_Uint8ClampedArray.res 344,926 344,214 -0.21%
packages/@rescript/runtime/Stdlib_Null.res 349,603 348,883 -0.21%
packages/@rescript/runtime/Stdlib_Array.resi 746,634 745,098 -0.21%
packages/@rescript/belt/src/Belt_HashMapInt.res 1,190,629 1,188,183 -0.21%
packages/@rescript/belt/src/Belt_HashMapString.res 1,191,337 1,188,895 -0.20%
packages/@rescript/belt/src/Belt_internalAVLtree.res 3,941,284 3,933,412 -0.20%
packages/@rescript/runtime/Stdlib_Temporal_PlainDate.res 407,039 406,235 -0.20%
packages/@rescript/runtime/Stdlib_Temporal_ZonedDateTime.res 581,114 579,970 -0.20%
packages/@rescript/runtime/Primitive_exceptions.res 207,901 207,493 -0.20%
packages/@rescript/runtime/Primitive_bigint.res 181,841 181,497 -0.19%
packages/@rescript/runtime/Stdlib_Object.res 246,460 246,000 -0.19%
packages/@rescript/runtime/Stdlib_Temporal_Duration.res 377,976 377,272 -0.19%
packages/@rescript/belt/src/Belt_Set.res 932,088 930,364 -0.18%
packages/@rescript/belt/src/Belt_MutableMap.res 1,459,148 1,456,450 -0.18%
packages/@rescript/belt/src/Belt_MutableMapString.res 1,291,746 1,289,394 -0.18%
packages/@rescript/belt/src/Belt_MutableMapInt.res 1,291,463 1,289,113 -0.18%
packages/@rescript/runtime/Primitive_int.res 176,287 175,967 -0.18%
packages/@rescript/runtime/Primitive_string.res 163,632 163,336 -0.18%
packages/@rescript/runtime/Stdlib_AsyncIterableIterator.res 241,203 240,767 -0.18%
packages/@rescript/runtime/Stdlib_Type.res 204,444 204,076 -0.18%
packages/@rescript/runtime/Stdlib_BigInt.res 209,476 209,108 -0.18%
packages/@rescript/runtime/Stdlib_Console.res 377,726 377,066 -0.17%
packages/@rescript/belt/src/Belt_MutableMap.resi 407,490 406,782 -0.17%
packages/@rescript/runtime/Stdlib_Math.resi 332,942 332,366 -0.17%
packages/@rescript/belt/src/Belt_Option.resi 246,170 245,750 -0.17%
packages/@rescript/runtime/Stdlib_Promise.res 371,448 370,820 -0.17%
packages/@rescript/runtime/Stdlib_Ordering.res 154,046 153,786 -0.17%
packages/@rescript/belt/src/Belt_internalSetInt.res 788,501 787,171 -0.17%
packages/@rescript/belt/src/Belt_internalSetString.res 789,694 788,362 -0.17%
packages/@rescript/belt/src/Belt_Option.res 403,611 402,939 -0.17%
packages/@rescript/belt/src/Belt_MapDict.resi 533,107 532,221 -0.17%
packages/@rescript/belt/src/Belt_MapDict.res 1,875,071 1,871,987 -0.16%
packages/@rescript/belt/src/Belt_MapString.res 1,333,987 1,331,797 -0.16%
packages/@rescript/belt/src/Belt_MapInt.res 1,333,449 1,331,265 -0.16%
packages/@rescript/runtime/Stdlib_AsyncGenerator.res 224,175 223,811 -0.16%
packages/@rescript/runtime/Stdlib_Temporal_PlainTime.res 322,879 322,355 -0.16%
packages/@rescript/runtime/Stdlib_IterableIterator.res 186,264 185,964 -0.16%
packages/@rescript/belt/src/Belt_MutableQueue.res 847,634 846,278 -0.16%
packages/@rescript/runtime/Stdlib_Date.resi 624,268 623,272 -0.16%
packages/@rescript/runtime/Stdlib_String.resi 504,688 503,884 -0.16%
packages/@rescript/belt/src/Belt_internalMapInt.res 1,610,677 1,608,157 -0.16%
packages/@rescript/belt/src/Belt_internalMapString.res 1,612,527 1,610,005 -0.16%
packages/@rescript/runtime/Stdlib_Console.resi 422,754 422,094 -0.16%
packages/@rescript/runtime/Stdlib_Temporal_PlainYearMonth.res 387,018 386,414 -0.16%
packages/@rescript/runtime/Primitive_list.res 213,196 212,864 -0.16%
packages/@rescript/runtime/Dom_storage.res 169,942 169,678 -0.16%
packages/@rescript/belt/src/Belt_HashMapString.resi 216,385 216,049 -0.16%
packages/@rescript/belt/src/Belt_HashMapInt.resi 216,500 216,164 -0.16%
packages/@rescript/belt/src/Belt_MutableQueue.resi 209,492 209,168 -0.15%
packages/@rescript/belt/src/Belt_MutableSet.resi 407,088 406,464 -0.15%
packages/@rescript/belt/src/Belt_Map.resi 597,409 596,500 -0.15%
packages/@rescript/runtime/Stdlib_Pair.res 168,525 168,269 -0.15%
packages/@rescript/belt/src/Belt_SetInt.res 1,413,088 1,410,944 -0.15%
packages/@rescript/belt/src/Belt_SetString.res 1,413,817 1,411,673 -0.15%
packages/@rescript/runtime/Stdlib_IteratorObject.res 264,450 264,050 -0.15%
packages/@rescript/runtime/Stdlib_RegExp.res 164,130 163,882 -0.15%
packages/@rescript/belt/src/Belt_SortArray.resi 256,541 256,157 -0.15%
packages/@rescript/runtime/Stdlib_JSON.res 302,239 301,787 -0.15%
packages/@rescript/belt/src/Belt_internalAVLset.resi 371,093 370,541 -0.15%
packages/@rescript/runtime/Stdlib_BigInt.resi 187,480 187,204 -0.15%
packages/@rescript/runtime/Stdlib_Global.res 141,938 141,730 -0.15%
packages/@rescript/belt/src/Belt_SetDict.res 1,634,169 1,631,785 -0.15%
packages/@rescript/belt/src/Belt_internalAVLtree.resi 480,017 479,321 -0.14%
packages/@rescript/runtime/Stdlib_Set.res 214,234 213,926 -0.14%
packages/@rescript/runtime/Stdlib_Temporal_Instant.res 310,488 310,044 -0.14%
packages/@rescript/belt/src/Belt_HashSetString.resi 176,274 176,022 -0.14%
packages/@rescript/belt/src/Belt_HashSetInt.resi 176,387 176,135 -0.14%
packages/@rescript/runtime/Stdlib_Float.res 221,240 220,924 -0.14%
packages/@rescript/runtime/Stdlib_JsError.resi 186,162 185,898 -0.14%
packages/@rescript/runtime/Primitive_float.res 149,645 149,433 -0.14%
packages/@rescript/belt/src/Belt_MutableStack.res 413,965 413,385 -0.14%
packages/@rescript/runtime/Stdlib_Intl_Locale.res 199,881 199,601 -0.14%
packages/@rescript/runtime/Stdlib_DataView.res 231,761 231,437 -0.14%
packages/@rescript/belt/src/Belt_Set.resi 447,971 447,347 -0.14%
packages/@rescript/belt/src/Belt_SetDict.resi 414,166 413,590 -0.14%
packages/@rescript/runtime/Jsx.res 122,098 121,930 -0.14%
packages/@rescript/runtime/Stdlib_Result.resi 305,424 305,004 -0.14%
packages/@rescript/belt/src/Belt_Range.resi 177,268 177,028 -0.14%
packages/@rescript/runtime/Stdlib_Generator.res 209,917 209,633 -0.14%
packages/@rescript/runtime/Stdlib_Option.resi 241,144 240,820 -0.13%
packages/@rescript/runtime/Stdlib_Map.res 210,049 209,777 -0.13%
packages/@rescript/runtime/Stdlib_IteratorObject.resi 241,227 240,915 -0.13%
packages/@rescript/runtime/Stdlib_Dict.resi 244,911 244,599 -0.13%
packages/@rescript/runtime/Stdlib_Global.resi 156,337 156,145 -0.12%
packages/@rescript/runtime/Stdlib_JSON.resi 239,282 238,990 -0.12%
packages/@rescript/runtime/Primitive_object_extern.res 114,734 114,594 -0.12%
packages/@rescript/runtime/Stdlib_Int.resi 207,249 206,997 -0.12%
packages/@rescript/belt/src/Belt_Result.resi 247,960 247,660 -0.12%
packages/@rescript/belt/src/Belt_MutableStack.resi 170,428 170,224 -0.12%
packages/@rescript/runtime/Stdlib_Temporal_PlainMonthDay.res 270,970 270,646 -0.12%
packages/@rescript/runtime/Stdlib_DataView.resi 271,148 270,824 -0.12%
packages/@rescript/runtime/Stdlib_Nullable.resi 204,247 204,007 -0.12%
packages/@rescript/runtime/Stdlib_Promise.resi 376,507 376,067 -0.12%
packages/@rescript/runtime/Stdlib_Null.resi 208,735 208,495 -0.11%
packages/@rescript/runtime/Stdlib_RegExp.resi 189,282 189,066 -0.11%
packages/@rescript/runtime/Stdlib_Set.resi 232,564 232,300 -0.11%
packages/@rescript/belt/src/Belt_HashSet.resi 226,843 226,591 -0.11%
packages/@rescript/belt/src/Belt_HashMap.resi 303,382 303,046 -0.11%
packages/@rescript/belt/src/Belt_Result.res 439,339 438,879 -0.10%
packages/@rescript/runtime/Stdlib_Float.resi 195,361 195,157 -0.10%
packages/@rescript/belt/src/Belt_internalBucketsType.res 299,013 298,705 -0.10%
packages/@rescript/runtime/Stdlib_Map.resi 221,621 221,393 -0.10%
packages/@rescript/belt/src/Belt_Id.resi 261,547 261,283 -0.10%
packages/@rescript/runtime/Dom_storage2.res 119,942 119,822 -0.10%

Instructions

In total: 9,664,672,297 → 9,665,362,885 (+0.01%).

Benchmark Base Head Change
stress/ObjectFields.res 950,039,985 952,026,043 +0.21%

Output size

In total: 25,569,598 → 25,569,606 (±0.00%).

None of the 13 benchmarks changed by 0.1% or more.

Pull request c63c67a compared with base 70da3d1 in this run.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

Changelog

💅 Polish

  • Walk the parameters of a function type without allocating a closure, so the compiler allocates about 0.2% less.

Semantic Diff

1 commit · Full page

Visit an arrow's argument types without a closure

c63c67a · JonoPrest · Nov 09, 2026, 14:40 UTC

Why

iter_type_expr visited the argument types of a Tarrow with List.iter (fun {typ} -> f typ), which allocates a closure each time it reaches an arrow type. Many walks over types go through it (copying, marking, levels, occur checks), and function types are common.

The arguments are now visited by a recursive function that takes f. The order of the visits is unchanged.

Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -0.22% in total (-0.20% for the files compiled one by one, -0.24% in the builds of tests/tests), stress/NestedClosures.res -0.89%. On a 552 module React app (clean build, one domain) the build allocates 0.18% fewer words.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants