swc-project / swc

Rust-based platform for the Web
https://swc.rs
Apache License 2.0
31.28k stars 1.23k forks source link

Left-hand-side with index operator substituted by value in array destructuring #9739

Open simeonborko opened 1 week ago

simeonborko commented 1 week ago

Describe the bug

Let's have a swap of values in array using destructuring:

const arr = ['a', 'b'];
[arr[0], arr[1]] = [arr[1], arr[0]];

It gets compiled into:

['a', 'b'] = [
    'b',
    'a'
];

which is obviously incorrect: SyntaxError: Invalid destructuring assignment target

The playground link points to specific code from the molstar library, however, above code is the minimal example.

Input code

// source: https://github.com/molstar/molstar/blob/85b72ae3b0bef58927b15db2e321236609156c05/src/mol-math/misc.ts#L43

export function spiral2d(radius: number) {
    let x = 0;
    let y = 0;
    const delta = [0, -1];
    const size = radius * 2 + 1;
    const halfSize = size / 2;
    const out: [number, number][] = [];

    for (let i = Math.pow(size, 2); i > 0; --i) {
        if ((-halfSize < x && x <= halfSize) && (-halfSize < y && y <= halfSize)) {
            out.push([x, y]);
        }

        if (x === y || (x < 0 && x === -y) || (x > 0 && x === 1 - y)) {
            [delta[0], delta[1]] = [-delta[1], delta[0]]; // change direction
        }

        x += delta[0];
        y += delta[1];
    }
    return out;
}

Config

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": 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,
    },
    "transform": {
      "constModules": {"globals": {"debug": {"IS_DEV_MODE": "false"}}}
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.9.2&code=H4sIAAAAAAAAA3VSwW6DMAy9V%2Bo%2FWJo0wQYNpKPt2tIv2E47Ig4EwogEBCVBK1v770tKoUXTfCD4%2BcV%2BtoMQSN6KlG6hUKqRW4Q%2BmSpaskh5hSpeSpWI8SQlJ2gTkDVO6JJ4hObB5hWviR9kBNMl9vFytfJe%2FWCVegGSIjU33SpRBaqYTBdKPry9LOez%2BYweGy4U5G2dKsZrkA0TSYkzSyQZa%2BUW6rYiVNjwM5%2BBtpIqOEII3u7md3d%2BymupIKOlSjQaeQ64fjyJSfZNdajPD0%2BA4Rn8CaNIyvyjZ13ICPAkzlu1hagX5lwFxlFs6plSPTXnAiyjjmn8XXe%2BaPiXZfI5gO2dhg9aNLguG3szxnKwLHdUsNfNPj7qzz4cZdkGmXA6g3QTziSpMS160bSysKKjA11s727h86B5EKAHHIY64elk%2Fvfg9RoM6Hb2FT7cwz640P0tGl0WEXmx068k8uPLmNzBG3AvjneAEKRFUn9SyJigl%2Ffwj8gjPIfjzbtOuhs%2Bbv3cH4KqVtRmDBo%2F%2FwLsEprO7wIAAA%3D%3D&config=H4sIAAAAAAAAA31VPY%2FbMAzd71cEmjsUGTp0vivQIehQ4FZBsShHV1kyRCqXIPB%2FLy07H5fQ2Sw%2BPlLix%2FPpZbVSH9ion6sTf%2FKhNxkhX85swWMkc2CLomMP2GTfk%2Fp2RglHyJmAUE3DhCgyuQUaWYDr7%2Bv1zFAhJYQzY7Z1Pnp3vM3ZpK7PgHhjYyuHLB1Ewq%2F8GcvpcwQol1v7NqUAJj5BtEHtI0ELWQrcpBBMj6D3JgtRxpua7DFJKUawEFjd59SLeLSefIqc8xG1YKxukgUB8hka8nuQaJyLaRH5ecJ7KmxhW9q29vmODXsTiiEhJxxqS%2Fi2QtRd8kjalSiVcAIXajCBc3Hvmd7pDFRyfOR9JB8XevIPgCsQDGI0HUhxq4fjeVpiu6dMHx2PLB0FnOdbemWElouqvXdCZcfKQCYvdTODLQ2MlW2k68zwQvnQW9DgHM%2BKEBo%2FPTU7Kem46MkJAPfXOGmqJkBftnABHxfiCfyLX0nygM0enaHdMorHbpvCkwQd0C7ZJw7cCkrLcGaVOPTLeIkWeDTAii4FK%2FAoArwAlHSoevkwG7weHFG3IW2vMjE7DBcd7kxs7%2Ff9osWZZc6l3H2VWE67SbaEOgEndU1wUlUf6tfvv%2Fr17V1v%2Fry%2BjWJeo6thGKYEL3MS1dVA19%2FIOEGT%2BP9QV6ezzl%2FuqDxuzsz6rOE%2FQnOQmpIGAAA%3D

SWC Info output

No response

Expected behavior

No substitution of left-hand-side in array destructuring.

Actual behavior

Left side of array destructuring replaced by values.

Version

1.9.2

Additional context

Version 1.2.249 works as expected. In version 1.3.107 it's broken. So the bug may have started during development of 1.3.

Workaround: Turn off Compress. Even if you disable all Compress Options, the bug still occurs. You need to turn off Compress.

magic-akari commented 1 week ago

Investigation: bb02cdd26ed863649c6ec8ef9c5cbdaece743b9b is the first bad commit