Skip to content

typedarray: use locale-sensitive separator in %TypedArray%.prototype.toLocaleString#5089

Merged
jedel1043 merged 10 commits intoboa-dev:mainfrom
mrhapile:fix/typedarray-tolocalestring-intl-separator
Mar 18, 2026
Merged

typedarray: use locale-sensitive separator in %TypedArray%.prototype.toLocaleString#5089
jedel1043 merged 10 commits intoboa-dev:mainfrom
mrhapile:fix/typedarray-tolocalestring-intl-separator

Conversation

@mrhapile
Copy link
Contributor

Summary

Update %TypedArray%.prototype.toLocaleString to use a locale-sensitive separator when the intl feature is enabled, aligning its behavior with Array.prototype.toLocaleString.

ref - #5081

Previously, the TypedArray implementation always used the hardcoded separator ", ". When the intl feature is enabled, Array.prototype.toLocaleString already derives the separator using ICU's ListFormatter. This PR updates the TypedArray implementation to use the same locale-aware separator logic.

When the intl feature is disabled, the implementation correctly falls back to ", ".

Changes

  • Use ICU ListFormatter via the intl_provider to compute a locale-sensitive separator when the intl feature is enabled.
  • Fall back to the default separator ", " when intl is disabled.
  • Hoist extraction of locales and options arguments outside the iteration loop to avoid repeated lookups.
  • Remove the unused utf16 import from the module.

Specification

This aligns the implementation with:

  • ECMAScript §23.2.3.31
    %TypedArray%.prototype.toLocaleString

which specifies that the algorithm should behave the same as:

  • ECMAScript §23.1.3.32
    Array.prototype.toLocaleString

except that TypedArrayLength is used instead of LengthOfArrayLike.

Verification

The following checks were performed:

  • cargo fmt
  • cargo clippy
  • cargo test
  • Test262 tests for TypedArray locale string conversion:
Screenshot 2026-03-15 at 8 27 06 AM

All existing tests pass and no regressions were introduced.

Notes

The behavior now matches the locale-sensitive list separator behavior used by Array.prototype.toLocaleString when intl support is enabled.

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile mrhapile requested a review from a team as a code owner March 15, 2026 03:07
Copilot AI review requested due to automatic review settings March 15, 2026 03:07
@github-actions github-actions bot added C-Builtins PRs and Issues related to builtins/intrinsics Waiting On Review Waiting on reviews from the maintainers labels Mar 15, 2026
@github-actions github-actions bot added this to the v1.0.0 milestone Mar 15, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates %TypedArray%.prototype.toLocaleString to use the same locale-sensitive list separator logic as Array.prototype.toLocaleString when the intl feature is enabled, keeping behavior aligned with the spec and existing array behavior.

Changes:

  • Compute a locale-aware separator via ICU ListFormatter behind the intl feature flag.
  • Fall back to the default ", " separator when intl is disabled.
  • Hoist locales/options extraction outside the iteration loop and remove the unused utf16 import.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@github-actions
Copy link

github-actions bot commented Mar 15, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,963 52,963 0
Passed 50,073 49,935 -138
Ignored 2,072 2,207 +135
Failed 818 821 +3
Panics 0 0 0
Conformance 94.54% 94.28% -0.26%
Broken tests (3):
test/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js (previously Passed)
test/intl402/DateTimeFormat/prototype/toStringTag/toString.js (previously Passed)
test/intl402/Number/prototype/toLocaleString/throws-same-exceptions-as-NumberFormat.js (previously Passed)

Tested main commit: 34b2b74b541a8d3a62a8775e696e920217756e71
Tested PR commit: 6629cc9cfb930904b60d97e1b2c4db99d94052a4
Compare commits: 34b2b74...6629cc9

Preallocate the result buffer to reduce reallocations when
concatenating separator and element strings, similar to the
Array.prototype.toLocaleString implementation.

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates %TypedArray%.prototype.toLocaleString to use the same locale-sensitive list separator behavior as Array.prototype.toLocaleString when the intl feature is enabled, while keeping the ", " fallback when intl is disabled.

Changes:

  • Use ICU ListFormatter (via intl_provider) to compute a locale-sensitive separator under cfg(feature = "intl").
  • Hoist locales/options extraction outside the element iteration and remove the unused utf16 import.
  • Adjust separator handling to work with JsString (iterating code units) and pre-allocate in join.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Reserve capacity for the result buffer in %TypedArray%.prototype.toLocaleString
to reduce repeated reallocations when concatenating separators and element
strings. This mirrors the approach used in Array.prototype.toLocaleString.

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@codecov
Copy link

codecov bot commented Mar 15, 2026

Codecov Report

❌ Patch coverage is 0% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.23%. Comparing base (6ddc2b4) to head (6629cc9).
⚠️ Report is 884 commits behind head on main.

Files with missing lines Patch % Lines
core/engine/src/builtins/typed_array/builtin.rs 0.00% 9 Missing ⚠️
core/engine/src/builtins/intl/number_format/mod.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #5089       +/-   ##
===========================================
+ Coverage   47.24%   59.23%   +11.99%     
===========================================
  Files         476      571       +95     
  Lines       46892    63099    +16207     
===========================================
+ Hits        22154    37379    +15225     
- Misses      24738    25720      +982     

☔ 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.

Comment on lines +2509 to +2527
use crate::builtins::intl::locale::default_locale;
use icu_list::{
ListFormatter, ListFormatterPreferences, options::ListFormatterOptions,
};

let locale = default_locale(context.intl_provider().locale_canonicalizer()?);
let preferences = ListFormatterPreferences::from(&locale);
let formatter = ListFormatter::try_new_unit_with_buffer_provider(
context.intl_provider().erased_provider(),
preferences,
ListFormatterOptions::default(),
)
.map_err(|e| JsNativeError::typ().with_message(e.to_string()))?;

// Ask ICU for the list pattern literal by formatting two empty elements.
// For many locales this yields ", ", but it may differ.
js_string!(
formatter.format_to_string(std::iter::once("").chain(std::iter::once("")))
)
Copy link
Member

Choose a reason for hiding this comment

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

In this case we kinda don't want to follow the implementation of Array, because it would create one NumberFormat per element, which is extremely inefficient

Instead, create a NumberFormat and a ListFormat then do a format of all numbers followed by a format with ListFormat

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile mrhapile requested a review from nekevss as a code owner March 15, 2026 05:47
@github-actions github-actions bot added the C-Intl Changes related to the `Intl` implementation label Mar 15, 2026
@mrhapile mrhapile requested a review from jedel1043 March 15, 2026 05:48
@jedel1043
Copy link
Member

You didn't address my comment

@mrhapile
Copy link
Contributor Author

@jedel1043 I did attempt the shared NumberFormat + ListFormatter approach, but it caused several Test262 failures (particularly for BigInt TypedArrays). To keep the implementation spec-correct for now, I temporarily removed the NumberFormat change and kept the ListFormatter.

@mrhapile
Copy link
Contributor Author

I'm currently investigating how to correctly integrate a shared NumberFormat while preserving full Test262 conformance , working on it will update sooon!!!

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile mrhapile marked this pull request as draft March 15, 2026 08:34
@mrhapile
Copy link
Contributor Author

right now
Results (ECMAScript Next):
Total tests: 39
Passed tests: 19
Ignored tests: 0
Failed tests: 20

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile
Copy link
Contributor Author

Results (ECMAScript Next):
Total tests: 39
Passed tests: 29
Ignored tests: 0
Failed tests: 10 (0 panics)
Conformance: 74.36%

…g shared NumberFormat optimization

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile mrhapile force-pushed the fix/typedarray-tolocalestring-intl-separator branch from 3b43a7c to b78e36f Compare March 15, 2026 11:26
…d ListFormatter

Avoid creating a NumberFormat per element by reusing a single
NumberFormat and ListFormatter instance for the entire typed array.

Falls back to the spec path when:
- Number.prototype.toLocaleString is overridden
- elements contain NaN or Infinity
- the typed array uses BigInt

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@jedel1043
Copy link
Member

I see what's happening. The test262 suite specifically tests that you call Number.prototype.toLocaleString for all elements... that's kinda bad

Okay, I guess we'll have to return to the old approach of using the separator and manually calling toLocaleString. I'll think of a way to optimise this in the future.

@mrhapile
Copy link
Contributor Author

@jedel1043 nahh now I have updated it I was just confirming and testing things before making this pr ready for review

@mrhapile
Copy link
Contributor Author

Screenshot 2026-03-15 at 5 37 18 PM

@mrhapile mrhapile marked this pull request as ready for review March 15, 2026 12:31
@jedel1043
Copy link
Member

I did see that, but I still put my comment becusse if the spec requires you to call Number.prototype.toLocaleString, then I don't think we should do special handling in TypedArray.prototype.toLocaleString. We should instead optimize Number.prototype.toLocaleString directly

@mrhapile
Copy link
Contributor Author

mrhapile commented Mar 15, 2026

should I revert it back to the simple approach (the first one I proposed) or wait for further instructions??

@jedel1043
Copy link
Member

yep, revert back

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
/// [spec]: https://tc39.es/ecma262/#sec-number.prototype.tolocalestring
#[inline]
#[must_use]
pub fn number_prototype_to_locale_string(&self) -> JsFunction {
Copy link
Member

Choose a reason for hiding this comment

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

We don't need this anymore since the changes were reverted

@jedel1043 jedel1043 added Waiting On Author Waiting on PR changes from the author and removed Waiting On Review Waiting on reviews from the maintainers labels Mar 16, 2026
…trinsic

Signed-off-by: mrhapile <allinonegaming3456@gmail.com>
@mrhapile mrhapile requested a review from jedel1043 March 18, 2026 06:00
Copy link
Member

@jedel1043 jedel1043 left a comment

Choose a reason for hiding this comment

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

LGTM!

@jedel1043 jedel1043 added this pull request to the merge queue Mar 18, 2026
@jedel1043 jedel1043 added A-Enhancement New feature or request and removed Waiting On Author Waiting on PR changes from the author labels Mar 18, 2026
Merged via the queue into boa-dev:main with commit daf86d3 Mar 18, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Enhancement New feature or request C-Builtins PRs and Issues related to builtins/intrinsics C-Intl Changes related to the `Intl` implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants