Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minifier incorrectly inlines object property with duplicated key from spreaded object #9498

Closed
hyp3rflow opened this issue Aug 26, 2024 · 3 comments · Fixed by #9507
Closed
Assignees
Labels
Milestone

Comments

@hyp3rflow
Copy link
Contributor

Describe the bug

Minifier correctly inlines object initialization using spreading operator, however inlining property access from initialized object points to the value from spreaded object even if new property value exists.

Input code

const x = {a: 1};
const y = {...x, a: 2};
console.log(y.a);

Config

{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": false
    },
    "target": "es2022",
    "loose": false,
    "minify": {
      "compress": {
        "arguments": false,
        "arrows": true,
        "booleans": true,
        "booleans_as_integers": false,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": false,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true
      },
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.7.18&code=H4sIAAAAAAAAA0vOzysuUahQsFWoTrRSMKy15koGi1SCRPT09Cp0FIDiRlDx%2FJxUvZz8dI1KvURNawA8alvVOwAAAA%3D%3D&config=H4sIAAAAAAAAA32UO3LjMAyG%2B5zCozrFjostcoDtcgYOTYIyvXxoCNCxJuO7L0TJj40hdRI%2B%2FAAJgPh%2B2%2B26E5ruY%2FfNn%2Fwz6IJQ7v9swTGRvrClAxM1muIH6t5v9IQTcjogNNN1Jh3p0gM1Fe5%2F7feLogs5I9wUiy365N34nNPkOBRAfLKxlUPWCInwf%2F3CSv6aAJX6bD%2FkHECnDaI0Kp8IeihSYJND0AOCOusiRJlOqovHLKWYYCWwaih5EHmynnxOnPOVWtBWmWxBQL6AIX8GSca5WJaQryfcp2ELh9r3rc8%2F1HDWoWoScsKltYRPK0Q9Zo%2BkXE1SCWe4UoMZLsX9qfROFaBa0qvulH1a6clfAK5A0IhJR5DiNg%2FH87SmdptKnxyPLI0C5%2FmWbpmg56Iq751Q2akyUMhL3Sxgq4GpskY6zoJXyofeggLneFaE0PjlyRylpDQOkJ0AuL%2FaSVM1A3V%2FhSt8ehAb%2BA%2FfkuQBWzyipuM6xTEecthIEIGO2W44cCsor%2BPCW%2BIyrPOaLPBogBVdKjbwugT4AVBWoe3Ll9ng58ERVR%2Fy4bEmFofrfQ9HnfrHe59X8dvi0MVsa4PLkp%2F6O6%2Fm393D6baF7wfvPH7elC3p9R%2BoYzQdMAYAAA%3D%3D

SWC Info output

No response

Expected behavior

y.a should be evaluated as 2 from y's initialization.

Actual behavior

No response

Version

1.7.18

Additional context

No response

@kdy1 kdy1 added this to the Planned milestone Aug 27, 2024
@kdy1 kdy1 self-assigned this Aug 27, 2024
@kdy1
Copy link
Member

kdy1 commented Aug 28, 2024

Investigation

The sequences pass does not stop on spread properties.

  TRACE  sequences: Trying to merge `y#2 = {
    ...{
        a: 1
    },
    a: 2
}` => `y#2`
    at crates/swc_ecma_minifier/src/compress/optimize/sequences.rs:2046
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2.a"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "console#1.log(y#2.a)"
    in merge_sequences_in_exprs with len: 3
    in merge_sequences_in_stmts with items_len: [0, 3]
    in merge_sequences_in_stmts
    in handle_stmt_likes
    in visit_mut_module_items
    in apply full optimizer
    in optimize with pass: 1
    in compress ast
    in minify
    in compress-only

  DEBUG  sequences: Inlining sequential expressions (`y#2`), kind: "change"
    at crates/swc_ecma_minifier/src/compress/optimize/sequences.rs:2539
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2.a"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "console#1.log(y#2.a)"
    in merge_sequences_in_exprs with len: 3
    in merge_sequences_in_stmts with items_len: [0, 3]
    in merge_sequences_in_stmts
    in handle_stmt_likes
    in visit_mut_module_items
    in apply full optimizer
    in optimize with pass: 1
    in compress ast
    in minify
    in compress-only

  DEBUG  sequences: Dropping inlined variable, kind: "change"
    at crates/swc_ecma_minifier/src/compress/optimize/sequences.rs:2399
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "y#2.a"
    in merge_sequential_expr with a: "y#2 = {\n    ...{\n        a: 1\n    },\n    a: 2\n}", b: "console#1.log(y#2.a)"
    in merge_sequences_in_exprs with len: 3
    in merge_sequences_in_stmts with items_len: [0, 3]
    in merge_sequences_in_stmts
    in handle_stmt_likes
    in visit_mut_module_items
    in apply full optimizer
    in optimize with pass: 1
    in compress ast
    in minify
    in compress-only

@kdy1
Copy link
Member

kdy1 commented Aug 28, 2024

Well, investigation was wrong.

console.log({
    ...{
        a: 1
    },
    a: 2
}.a);

becomes

console.log(1);

So the cause is expr_simplifier

@swc-bot
Copy link
Collaborator

swc-bot commented Oct 3, 2024

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Oct 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
6 participants
@kdy1 @hyp3rflow @swc-bot and others