You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Template literal interpolating a Symbol stringifies instead of throwing TypeError #10609
A template literal interpolating a Symbol silently stringifies it, where the spec requires a TypeError. String concatenation on the same value already throws correctly, so this is a gap in the template path specifically, not in ToString.
ToString(argument) (ECMA-262 7.1.17) throws for a Symbol, and template substitution reaches it through GetValue → ToString in §13.2.8.6. String(sym) and sym.toString() are the two legal ways to stringify one and must keep working.
template threw TypeError: Cannot convert a Symbol value to a string
concat threw TypeError: Cannot convert a Symbol value to a string
String(): Symbol(x)
toString(): Symbol(x)
multi threw TypeError: Cannot convert a Symbol value to a string
perry (clean main, built at c8cf450563)
Symbol(x)
concat threw TypeError: Cannot convert a Symbol value to a string
String(): Symbol(x)
toString(): Symbol(x)
aSymbol(x)b
Lines 2, 3 and 4 match. Lines 1 and 5 — the two template forms — should throw and do not.
Where to look
The + path throws, so the Symbol check exists and is reachable; the template path does not consult it. Templates desugar to a concat chain, and js_string_concat_chain's classify loop falls back to js_jsvalue_to_string for a pointer-tagged value, which stringifies a Symbol rather than rejecting it. The pairwise + helper rejects first. Worth checking whether the single-substitution form (`${s}`, which lowers to a bare StringCoerce with no chain) and the multi-part form need the check in different places.
Why it matters beyond conformance
Silently stringifying is the worse failure direction: a Symbol used as a key or brand that lands in a template produces a plausible-looking "Symbol(x)" string instead of failing, so the mistake propagates into output, keys or comparisons rather than surfacing where it happened.
Provenance
Found while measuring template-literal interpolation for #10576. Present identically on that PR's before and after binaries, so it is pre-existing on main and unrelated to that change.
Activity