The forms the first slice answers now lower: x.toLocaleString() (and an
explicit undefined locale) to icu.numFormatDefault, the argument-free
Date#toLocaleString/toLocaleTimeString to the ICU date formatters, and
Intl.Segmenter({ granularity: "word" }) to the ICU word iterator (a
literal language tag is the locale; the empty string is the default).
Sentence segmentation keeps its refusing construction in JavaScript
dependencies, the grapheme segmenter stays the engine-free fast path,
and the code notes the deletion I4 schedules.
The refusals that named these forms follow: the four stdlib hints, the
Intl identifier hint, the Date method hint and the Segmenter option
messages list what lowers and what still does not (locale negotiation,
options bags, toLocaleDateString, formatter values). The library mode
refuses the icu.* libCalls, whose ambient locale state and data file a
library archive cannot carry, and the ambient process.config comment says
what a compiled binary can honestly answer.
An argument that IS undefined (exactly undefined, or void) means the
absent form and lowers; one whose type merely includes undefined may hold
a locale or an options bag at run time, and the constructor cannot read
either, so it is refused rather than silently treated as absent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- new Intl.NumberFormat("en-US").format(x), the callable spelling, and x.toLocaleString("en-US") lower to one runtime formatter with default options: decimal notation, 0-3 fraction digits rounded half-up on the SHORTEST round-tripping decimal (ICU's rounding input, probed against Node — format(1.0005) is "1.001" though toFixed(3) answers "1.000"; 1e23 prints the shortest form's zeros, not the exact expansion), "," grouping, "∞"/"NaN" texts, and "-0" for negatives rounding to zero. The en-US/latn symbols are the whole embedded locale surface — no ICU is linked.
- The Ryū digit core factors out of scr_f64_to_str as scr_f64_digits (same bytes; the 1M-double oracle gate stays green) and feeds the formatter; a 30,000-double ad-hoc fuzz across magnitude regimes matched Node byte-for-byte on both backends.
- Every unlowered Intl form fences by NAME with its own reason: the environment-default locale a compiled binary cannot carry (no-locale forms), other locales and the rest of the namespace (DurationFormat, DateTimeFormat, PluralRules, getCanonicalLocales — ICU data the binary does not embed; Node 24's DurationFormat additionally throws V8-internal Temporal errors with embedded source paths, so byte parity there is a version-dependent landmine), options bags, formatter values (the composed form is the lowered shape), and non-number format arguments.
- Differential fixture 2562 pins the rounding discriminators, grouping, ±0/NaN/∞, tiny and huge edges, and both spellings byte-identically vs Node on both backends; the new intl diagnostics fixture pins every named fence, and the Intl hints across the identifier/member/type chokepoints now teach what lowers.