Repository: swc-project/swc (rust)

Issue:
Remove unused destructured array params when compressing
### Describe the feature

```javascript
const [a,b,c,d,e] = [1,2,3,4,5]
console.log(c)
```
can be compressed to
```javascript
const [,,c] = [1,2,3,4,5]
console.log(c)
```
however it's currently unchanged, resulting in
```javascript
const [a,b,c,d,e] = [1,2,3,4,5]
console.log(c)
```

### Babel plugin or link to the feature description

_No response_

### Additional context

[Playground link](https://play.swc.rs/?version=1.3.100&code=H4sIAAAAAAAAA0vOzysuUYhO1EnSSdZJ0UmNVbBViDbUMdIx1jHRMY3l5UoGKsjPSdXLyU%2FXSNbk5QIAS%2FIniDEAAAA%3D&config=H4sIAAAAAAAAA32UO3LjMAyG%2B5zCozrFjost9gDpcgYOTYIyvXxoCNCxJuO7L0TJj40hdRI%2B%2FAQIgPh%2B2%2B26E5ruz%2B6bP%2Fln0AWh3P%2FZgmMifWFLByZqNMUP1L3f6Akn5HRAaKbrTDrSpQdqKtz%2F2u8XRRdyRrgpFlv0ybvxOabJcSiA%2BGRjKx9ZIySazFQqvD%2Bjkr8E%2ByHnADptEKVR%2BUTQQ8H%2F81oyCUEPCOqsi3DKlKguHrMUYoKVwKqh5EHkyXryOXHMV2pBW2WyBQH5Aob8GSQZx2JZQr6ecJ%2BGLRxq37c2%2F1DDWYeqSYgJl9YRzlY49Zg9knI1SSWc4UoNZrgU96fSO1WAakmvulP2aaUnfwG4AkEjJh1BOrd5OB6nNbXbVPrkeGJpFDiPt3TLBD0XVXnvhMpOlYFCXupmAVsNTJU161QuA3oLCpzjSZHolydzlELSOEB2AuDuaifN1AzU%2FQ2u8Ok5bOAPviPJ47V4RE3HdYpjPOSwESACHbPdcOBGUF7HhXfEZVjnNVngwQArulRs4HUF8PhTVqEty5fJ4MfBJ6o%2B5MNjSSwO1%2FsSjjr1j9c%2B7%2BG3xaGL2dYGlw0%2F9Xfey7%2B7h9NtBd8T7zx%2B3pQt6PUfXN0gJS0GAAA%3D)

Pull request description:
fix(es/minifier): Fix removal of array pattern bindings
**Description:**


**Related issue:**

 - Closes #8670

Patch:
diff --git a/crates/swc_ecma_minifier/src/compress/optimize/unused.rs b/crates/swc_ecma_minifier/src/compress/optimize/unused.rs
index 14b810be9d..79ebff51d8 100644
--- a/crates/swc_ecma_minifier/src/compress/optimize/unused.rs
+++ b/crates/swc_ecma_minifier/src/compress/optimize/unused.rs
@@ -345,25 +345,22 @@ impl Optimizer<'_> {
             }
 
             Pat::Array(arr) => {
-                for (idx, elem) in arr.elems.iter_mut().enumerate() {
-                    match elem {
+                for (idx, arr_elem) in arr.elems.iter_mut().enumerate() {
+                    match arr_elem {
                         Some(p) => {
-                            if p.is_ident() {
-                                continue;
-                            }
-
                             let elem = init
                                 .as_mut()
                                 .and_then(|expr| self.access_numeric_property(expr, idx));
 
                             self.take_pat_if_unused(p, elem, is_var_decl);
+
+                            if p.is_invalid() {
+                                *arr_elem = None;
+                            }
                         }
                         None => {}
                     }
                 }
-
-                arr.elems
-                    .retain(|elem| !matches!(elem, Some(Pat::Invalid(..))))
             }
 
             Pat::Object(obj) => {


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/TODO.txt b/crates/swc_ecma_minifier/tests/TODO.txt
index 2031e7c8c4..cec001dfbd 100644
--- a/crates/swc_ecma_minifier/tests/TODO.txt
+++ b/crates/swc_ecma_minifier/tests/TODO.txt
@@ -184,7 +184,6 @@ harmony/issue_2874_2/input.js
 harmony/module_enabled/input.js
 harmony/module_mangle_scope/input.js
 harmony/regression_cannot_use_of/input.js
-hoist_props/contains_this_3/input.js
 hoist_props/hoist_function_with_call/input.js
 if_return/if_return_same_value/input.js
 if_return/if_var_return/input.js
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8670/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/8670/config.json
new file mode 100644
index 0000000000..b15be3b3e0
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8670/config.json
@@ -0,0 +1,5 @@
+{
+    "defaults": true,
+    "pure_getters": true,
+    "toplevel": true
+}
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8670/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/8670/input.js
new file mode 100644
index 0000000000..7b0444cf74
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8670/input.js
@@ -0,0 +1,2 @@
+const [a, b, c, d, e] = [1, 2, 3, 4, 5]
+console.log(c)
\ No newline at end of file
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8670/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/8670/output.js
new file mode 100644
index 0000000000..482e2841b0
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8670/output.js
@@ -0,0 +1,8 @@
+const [, , c, , ] = [
+    1,
+    2,
+    3,
+    4,
+    5
+];
+console.log(c);
diff --git a/crates/swc_ecma_minifier/tests/passing.txt b/crates/swc_ecma_minifier/tests/passing.txt
index f6a47e6515..d3f2f33b63 100644
--- a/crates/swc_ecma_minifier/tests/passing.txt
+++ b/crates/swc_ecma_minifier/tests/passing.txt
@@ -739,6 +739,7 @@ hoist/hoist_no_destructurings/input.js
 hoist/hoist_vars/input.js
 hoist_props/contains_this_1/input.js
 hoist_props/contains_this_2/input.js
+hoist_props/contains_this_3/input.js
 hoist_props/direct_access_1/input.js
 hoist_props/direct_access_2/input.js
 hoist_props/direct_access_3/input.js
diff --git a/crates/swc_ecma_minifier/tests/terser/compress/destructuring/unused_destructuring_declaration_complex_1/output.js b/crates/swc_ecma_minifier/tests/terser/compress/destructuring/unused_destructuring_declaration_complex_1/output.js
index 816d1b5609..be76f977eb 100644
--- a/crates/swc_ecma_minifier/tests/terser/compress/destructuring/unused_destructuring_declaration_complex_1/output.js
+++ b/crates/swc_ecma_minifier/tests/terser/compress/destructuring/unused_destructuring_declaration_complex_1/output.js
@@ -1,2 +1,10 @@
-const [, w, , x, { z: z }] = [1, 2, 3, 4, { z: 5 }];
+const [, , , x, { z: z }] = [
+    1,
+    2,
+    3,
+    4,
+    {
+        z: 5
+    }
+];
 console.log(x, z);