fix(minifier): prevent incorrect array.join("") to string concat for nullable elements#11546
Open
veeceey wants to merge 4 commits intoswc-project:mainfrom
Open
fix(minifier): prevent incorrect array.join("") to string concat for nullable elements#11546veeceey wants to merge 4 commits intoswc-project:mainfrom
veeceey wants to merge 4 commits intoswc-project:mainfrom
Conversation
…mization
Array.prototype.join converts null/undefined elements to empty strings,
but string concatenation with + converts them to "null"/"undefined".
This caused incorrect output when compress.evaluate was enabled for
arrays containing expressions that could evaluate to undefined/null.
For example:
["abc", cond ? undefined : "def"].join("") should produce "abc" when
cond is true, but was being converted to "abc" + (cond ? void 0 : "def")
which produces "abcundefined".
The fix bails out of the partial join optimization when non-literal
expressions that aren't guaranteed to be strings are present in the
array with an empty separator.
Closes swc-project#11545
🦋 Changeset detectedLatest commit: e7c4d9b The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
Binary Sizes
Commit: 0a09de5 |
kdy1
requested changes
Feb 15, 2026
Member
kdy1
left a comment
There was a problem hiding this comment.
CI failed. Can you fix it?
You can do UPDATE=1 cargo test from the minifier directory or swc directory to update the test refernces
…uard The previous approach using is_definitely_string was too conservative and blocked the join-to-concat optimization for function calls, variables, and other expressions that terser also optimizes. This caused 8 fixture test failures. Replace with may_produce_null_or_undefined which only bails out when an expression obviously produces null/undefined (direct null/undefined/void literals, or conditional expressions with nullable branches). This still prevents the incorrect transformation from swc-project#11545 while preserving terser-compatible behavior for other cases.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
|
Fixed the clippy issue — changed |
Author
|
CI is green now after the clippy fix — switched to is_some_and() as suggested. Would appreciate a re-review when you get a chance! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11545
When
compress.evaluateis enabled,compress_array_join_partialconverts[...].join("")to string concatenation with+. This is incorrect when array elements can beundefinedornull, becauseArray.prototype.joinconverts these to empty strings, while+converts them to"undefined"/"null".For example:
The fix adds a check in the empty-separator path of
compress_array_join_partialthat bails out when non-literal expressions aren't guaranteed to be strings (checked viais_definitely_string). This prevents the semantics-changing transformation while still allowing the optimization for safe cases like template literals and known string concatenations.All 471 exec tests pass, including 2 new tests covering the exact scenario from the issue.