🔎 Search Terms
api, getCompletionsAtPosition, includeSymbol, deadlock
🕗 Version & Regression Information
This bug couldn't be reproduced in any published version because it can only be triggered if the error described in #64132 were fixed
⏯ Playground Link
No response
💻 Code
(note: the reproduction must be run on a #64133 branch, or on main after the PR is merged)
- Create repro dir
mkdir /tmp/repro
cd /tmp/repro
npm init -y
npm add typescript@7.0.2
echo '{}' > tsconfig.json
- Create files
// export.ts
export const someValue = 1
// index.ts
const foo = {
}
// repro.mjs
import path from 'node:path'
import { API } from 'typescript/unstable/sync'
const api = new API()
const root = process.cwd()
const file = path.join(root, 'index.ts')
const tsconfigPath = path.join(root, 'tsconfig.json')
const snapshot = api.updateSnapshot({ openProject: tsconfigPath })
const project = snapshot.getProject(tsconfigPath)
console.log(project.checker.getCompletionsAtPosition(file, 15, { includeSymbol:true }))
- Run repro
🙁 Actual behavior
It hangs forever
🙂 Expected behavior
It returns completion items
Additional information about the issue
This happens because getCompletionsAtPosition uses a context with a checker API lifetime:
|
func (s *Session) handleGetCompletionsAtPosition(ctx context.Context, params *GetCompletionsAtPositionParams) (*CompletionInfoResponse, error) { |
|
if params.IncludeSymbol { |
|
ctx = core.WithCheckerLifetime(ctx, core.CheckerLifetimeAPI) |
|
} |
Because of this, there is only one persistent checker is the in checkerpool.
The same goroutine first acquires the checker here
|
checker, done := l.GetProgram().GetTypeCheckerForFile(ctx, file) |
|
defer done() |
Then it tries to acquire the same checker again here
|
ch, done := v.program.GetTypeChecker(ctx) |
|
defer done() |
As a result, it silently deadlocks and hangs indefinitely. There is no panic because other goroutines are still active.
🔎 Search Terms
api, getCompletionsAtPosition, includeSymbol, deadlock
🕗 Version & Regression Information
This bug couldn't be reproduced in any published version because it can only be triggered if the error described in #64132 were fixed
⏯ Playground Link
No response
💻 Code
(note: the reproduction must be run on a #64133 branch, or on
mainafter the PR is merged)🙁 Actual behavior
It hangs forever
🙂 Expected behavior
It returns completion items
Additional information about the issue
This happens because
getCompletionsAtPositionuses a context with a checker API lifetime:TypeScript/tsc/internal/api/session.go
Lines 4005 to 4008 in e73c923
Because of this, there is only one persistent checker is the in checkerpool.
The same goroutine first acquires the checker here
TypeScript/tsc/internal/ls/completions.go
Lines 431 to 432 in e73c923
Then it tries to acquire the same checker again here
TypeScript/tsc/internal/ls/autoimport/fix.go
Lines 853 to 854 in e73c923
As a result, it silently deadlocks and hangs indefinitely. There is no panic because other goroutines are still active.