Skip to content

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

Open
mrhapile wants to merge 9 commits intoboa-dev:mainfrom
mrhapile:fix/typedarray-tolocalestring-intl-separator
Open

typedarray: use locale-sensitive separator in %TypedArray%.prototype.toLocaleString#5089
mrhapile wants to merge 9 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,070 49,935 -135
Ignored 2,072 2,207 +135
Failed 821 821 0
Panics 0 0 0
Conformance 94.54% 94.28% -0.25%

Tested main commit: baaadfeeaf4a64f34e82cbbb9fee3ed4013495c0
Tested PR commit: b607b69648cb1accf98b6118a27f0715d5b7abfe
Compare commits: baaadfe...b607b69

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 51.72414% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.13%. Comparing base (6ddc2b4) to head (b607b69).
⚠️ Report is 865 commits behind head on main.

Files with missing lines Patch % Lines
core/engine/src/builtins/typed_array/builtin.rs 7.14% 13 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.13%   +11.88%     
===========================================
  Files         476      563       +87     
  Lines       46892    62691    +15799     
===========================================
+ Hits        22154    37071    +14917     
- Misses      24738    25620      +882     

☔ 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-Builtins PRs and Issues related to builtins/intrinsics C-Intl Changes related to the `Intl` implementation Waiting On Author Waiting on PR changes from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants