Repository: swc-project/swc (language: rust)

Issue:
Incorrect compressor behavior in switch
### Describe the bug

See example

### Input code

```typescript
const getString = () => {
  switch ("apple") {
    case 'apple':
      return '1';
    case 'banana':
      return '2';
  }
  return "3"
};


console.log(getString());
```


### Config

```json
{
 "jsc": {
  "parser": {
   "syntax": "ecmascript",
  },
  "target": "es5",
  "minify": {
    "mangle": false,
    "compress": true,
  }
 },
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.7.28&code=H4sIAAAAAAAAA0vOzysuUUhPLQkuKcrMS1ewVdDQVLC1U6jm5VJQKC7PLEnOUNBQSiwoyElV0oSIKigkJxanKqiDBdWtIEIKCkWpJaVFeQrqhurWyKqSEvOAEFOZEURZLYiAiikZK%2FFy1QKFQTAZ6LD8nFS9nPx0DbjzNDQ1rQEoac67sgAAAA%3D%3D&config=H4sIAAAAAAAAAzWMQQqFMAwF9z1FyNqtG28TSpSKrSWJoEjvbqz%2Fbx7MDLw7AK4acYI7AGAlUZYfAepVjE5H5JhJo6RqOHhq76CRLGw969g95lTSfP0PnKksGzvPtCkPn4x7rsKqrk2Oblt4P9sDpwS%2Bn48AAAA%3D

### SWC Info output

_No response_

### Expected behavior

```js
console.log('1');
```

### Actual behavior

```js
console.log('3');
```

### Version

1.7.28

### Additional context

_No response_


Discussion / hints:
Surprisingly, disabling the dead_code option in the compressor corrects the situation...

Fix patch:
diff --git a/.changeset/good-lions-design.md b/.changeset/good-lions-design.md
new file mode 100644
index 000000000000..15b155573d1e
--- /dev/null
+++ b/.changeset/good-lions-design.md
@@ -0,0 +1,6 @@
+---
+swc_core: patch
+swc_ecma_minifier: patch
+---
+
+fix(es/minifier): Only merge last if return
diff --git a/crates/swc_ecma_minifier/src/compress/optimize/if_return.rs b/crates/swc_ecma_minifier/src/compress/optimize/if_return.rs
index e5ad4d9de2b5..e7fe6b811c22 100644
--- a/crates/swc_ecma_minifier/src/compress/optimize/if_return.rs
+++ b/crates/swc_ecma_minifier/src/compress/optimize/if_return.rs
@@ -494,16 +494,16 @@ impl Optimizer<'_> {
         }
     }
 
-    fn can_merge_stmt_as_if_return(&self, s: &Stmt, _is_last: bool) -> bool {
+    fn can_merge_stmt_as_if_return(&self, s: &Stmt, is_last: bool) -> bool {
         // if !res {
         //     trace!("Cannot merge: {}", dump(s));
         // }
 
         match s {
             Stmt::Expr(..) => true,
-            Stmt::Return(..) => true,
+            Stmt::Return(..) => is_last,
             Stmt::Block(s) => {
-                s.stmts.len() == 1 && self.can_merge_stmt_as_if_return(&s.stmts[0], false)
+                s.stmts.len() == 1 && self.can_merge_stmt_as_if_return(&s.stmts[0], is_last)
             }
             Stmt::If(stmt) => {
                 matches!(&*stmt.cons, Stmt::Return(..))


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/9628/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/9628/input.js
new file mode 100644
index 000000000000..d72cd31502f7
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/9628/input.js
@@ -0,0 +1,11 @@
+const getString = () => {
+    switch ("apple") {
+        case "apple":
+            return "1";
+        case "banana":
+            return "2";
+    }
+    return "3";
+};
+
+console.log(getString());
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/9628/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/9628/output.js
new file mode 100644
index 000000000000..eaedf96c62f6
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/9628/output.js
@@ -0,0 +1,1 @@
+console.log("1");