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

Reachability analysis of never for yield* is unchecked #58582

Open
rixtox opened this issue May 20, 2024 · 2 comments
Open

Reachability analysis of never for yield* is unchecked #58582

rixtox opened this issue May 20, 2024 · 2 comments
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@rixtox
Copy link

rixtox commented May 20, 2024

πŸ”Ž Search Terms

reachability never

πŸ•— Version & Regression Information

It's observed in all TS versions.

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mAVAAjAUwG5oE4AoCUAXMgOJrrYCGUc2APOANZhwDuYANOltgHzIBvAFDJkUABbY2yAOTccMgNxCAvkKGhIsBCgC2lGGAKCRY7AE8To0eZhoANgBMU8vPmWiVyYIcr37lsLWyBAIAM5w9mgAdPZwAOa4Mj5gfgEy7qZqoqFgEVGxCUksUMjYaJQQ4pQARlEZympAA

πŸ’» Code

function* never(): Generator<unknown,never> {
  throw 'never';
}

function* main() {
  try {
    yield* never();
  } finally {
    console.log('finally');
  }
  console.log('not reachable');
}

πŸ™ Actual behavior

No error reported.

πŸ™‚ Expected behavior

There should be an error Unreachable code detected.(7027) at line 11 console.log('not reachable');.

Additional information about the issue

Reachability analysis is working for normal function: https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABGApgNxQJwBQEoBcy6WiA3gFCKJQAWmcA7ogOSoabMDc5AvueaEiwEiALYBDGGDxlK1TAE9ZVKmyx5uVHomBTxAG31KKKxBAQBnOPpQA6fXADm2ZrrAGjzXJsR8q5sCsbeycXMDgoREwUcQgacQAjGy9uPiA

It's broken for Promise and we have another issue tracking that one: #34955

Generator functions are being used as coroutine in libraries like co.js, Effect.js, redux-saga, Effection, and more. It's common to write a coroutine operator that suspend the thread forever, thus taking function never(): Generator<Instruction, never> signature. It would benefit users if the TypeScript control analysis can infer unreachability after yield* never().

@fatcerberus
Copy link

fatcerberus commented May 20, 2024

Related: #56363

I think this comes down to the known limitation wherein never-returning functions can only affect control flow for a naked function call (which is the root cause of #34955 too); here, the call is only part of the statement because the return value is being passed to yield*. So it's similar to how

function never(): never { throw Error(); }
const x = never();
console.log("unreachable, not an error");

doesn't have an unreachable-code error either.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jun 6, 2024
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 5.6.0 milestone Jun 6, 2024
@SamVerschueren
Copy link

Run into this as well

function foo(): never {
  throw new Error('foo');
}

(foo());

const x = foo();

console.log(foo());

foo();

// Only from this point forward it errors because of "unreachable"

console.log('hello');

I found this bug while I was looking into this bug which is somewhat related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

5 participants