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

@swc/helper _ts_generator wrong code exported #9110

Open
yf-yang opened this issue Jun 28, 2024 · 1 comment
Open

@swc/helper _ts_generator wrong code exported #9110

yf-yang opened this issue Jun 28, 2024 · 1 comment
Assignees
Labels
Milestone

Comments

@yf-yang
Copy link

yf-yang commented Jun 28, 2024

Describe the bug

@swc/helpers unexpectedly merges two different code paths.

Input code

function* test() {
  while (!False()) {
    // execute this line
    while (!False()) {
      // execute this line
      break;
    }
    // execute this line
    if (False()) {
      // NOT execute this line
      break;
    }

    // execute this line
    yield "correct";
    return;
  }

  // NOT execute this line
  yield "wrong";
  return;
}

function False() {
  return false;
}

for (const result of test()) {
  console.log(result);
}

Config

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "externalHelpers": true
  },
  "env": {
    "targets": "Chrome >= 48"
  }
}

Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.6.5&code=H4sIAAAAAAAAA42RPQ7CMAyFd07x6JQy0AOwM8LCBSA4bUSUSImjghB3p%2Flhg4gt8Xvfs2WraCVrZzdgCix6PFfAPGlDEOv92QQSfSkCwwC6k4xM4EkHGG0pCz%2F8DQK4eDrfdvnzaqdrBfEt%2BXA8%2FZfejn9oMld00nlPkrsCeeLobXpnvNGt4rN3dszwB11AVZeLOn6evuhQqVRczkNIZwMvWoiG4VS9RiGS5gxtjRtFcfQJfANPEoyouwEAAA%3D%3D&config=H4sIAAAAAAAAA1WPSw7DIAwF9zkF8rrbdtE79BCIOhERP9mOVBTl7oUE0maH3xszsA5KwcwGnmotxzIkTYx0ziXhHER%2FSgKSE7IhmwRuvRWu1agd4x5tRwOiaUKpW8j3hoOLkbHjLfM22DH%2FC030iZD5ClZUh8nhVTc0Jfj4XvayfaQ%2B9tA%2F4Ad12XkxWH71TaEFh%2B0LYuVI0xQBAAA%3D

SWC Info output

Operating System:
Platform: darwin
Arch: x64
Machine Type: x86_64
Version: Darwin Kernel Version 22.3.0: Mon Jan 30 20:42:11 PST 2023; root:xnu-8792.81.3~2/RELEASE_X86_64
CPU: (16 cores)
Models: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz

Binaries:
    Node: 20.9.0
    npm: 10.1.0
    Yarn: 1.22.19
    pnpm: 9.4.0

Relevant Packages:
    @swc/core: 1.6.5
    @swc/helpers: 0.5.11
    @swc/types: N/A
    

SWC Config:
    output: N/A
    .swcrc path: N/A

Next.js info:
    output: N/A

Expected behavior

The two break should not be merged together and yields "correct"

Actual behavior

Two break are merged, inner break directly breaks two while loops and yields "wrong"

Version

@swc/helpers: 0.5.11

Additional context

You can also play with https://github.com/yf-yang/swc-ts-generator-bug, but maybe the playground is enough.

pnpm i
pnpm swc src/index.ts -o index.js
pnpm tsx src/index.ts # correct
pnpm tsx index.js # wrong
@yf-yang yf-yang added the C-bug label Jun 28, 2024
@kdy1 kdy1 self-assigned this Jun 29, 2024
@kdy1 kdy1 added this to the Planned milestone Jun 29, 2024
@kdy1
Copy link
Member

kdy1 commented Jul 1, 2024

Related link: https://github.com/microsoft/TypeScript/blob/main/src/compiler/transformers/generators.ts

Investigation

tsc:

function test() {
    return __generator(this, function (_a) {
        switch (_a.label) {
            case 0:
                if (!!False()) return [3 /*break*/, 2];
                // execute this line


                // >>>>> >>>>>

                while (!False()) {
                    // execute this line
                    break;
                }
                // execute this line
                if (False()) {
                    // NOT execute this line
                    return [3 /*break*/, 2];
                }
                // execute this line
                return [4 /*yield*/, "correct"];
            case 1:
                // execute this line
                _a.sent();
                return [2 /*return*/];
            case 2:
                // NOT execute this line
                return [4 /*yield*/, "wrong"];
            case 3:
                // NOT execute this line
                _a.sent();
                return [2 /*return*/];
        }
    });
}

swc:

function test() {
    return _ts_generator(this, function(_state) {
        switch(_state.label){
            case 0:
                if (!!False()) return [
                    3,
                    2
                ];

                // execute this line


                // >>>>> >>>>>
                while(!False()){
                    // execute this line
                    return [
                        3,
                        2
                    ];
                }
                // execute this line
                if (False()) {
                    // NOT execute this line
                    return [
                        3,
                        2
                    ];
                }
                // execute this line
                return [
                    4,
                    "correct"
                ];
            case 1:
                _state.sent();
                return [
                    2
                ];
            case 2:
                // NOT execute this line
                return [
                    4,
                    "wrong"
                ];
            case 3:
                _state.sent();
                return [
                    2
                ];
        }
    });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants