typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Fix completion crash after closing bracket in contextually-typed array literals

Open Copilot opened this issue 2 weeks ago • 0 comments

Completions panic with "index out of range [-1]" when requested after ] in array literals with tuple context types:

let x: [number] = [123]/**/;  // Crash on completion

PR #2258 added special handling for OpenBracketToken and CommaToken in array literals but missed CloseBracketToken. When completing after ], the token falls through to the checker which calls IndexOfNode() on it, returning -1. This invalid index causes an out-of-bounds panic in getContextualTypeForElementExpression when indexing into the type arguments array.

Changes:

  • Added KindCloseBracketToken case in getContextualType() to return nil immediately—the cursor is outside the array literal, so no element contextual type applies
  • Added test case for the reported scenario
Original prompt

This section details on the original issue you should resolve

<issue_title>Crash for completions after end of array literal when contextually typed by tuple</issue_title> <issue_description>Basically just a continuation of https://github.com/microsoft/typescript-go/issues/2254, where microsoft/typescript-go#2258 didn't fully address one of the noted issues.

let x: [number] = [123]/**/;
[error] panic handling requesttextDocument/completionruntime error: index out of range [-1]goroutine 4688 [running]:
runtime/debug.Stack()
	runtime/debug/stack.go:26 +0x5e
github.com/microsoft/typescript-go/internal/lsp.(*Server).recover(0xc0001e4008, 0xc0127513b0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:701 +0x58
panic({0xca4c60?, 0xc00220fbf0?})
	runtime/panic.go:783 +0x132
github.com/microsoft/typescript-go/internal/checker.(*Checker).getContextualTypeForElementExpression.func1(0xc000df5dc0)
	github.com/microsoft/typescript-go/internal/checker/checker.go:28915 +0x30d
github.com/microsoft/typescript-go/internal/checker.(*Checker).mapTypeEx(0xc002413172?, 0xc006beb508?, 0xc002413188?, 0x53?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:24914 +0x118
github.com/microsoft/typescript-go/internal/checker.(*Checker).getContextualTypeForElementExpression(0xc0068cd908?, 0xc00382f4a0?, 0x2?, 0xc0024131f0?, 0xc005b85c50?, 0xf66840?)
	github.com/microsoft/typescript-go/internal/checker/checker.go:28910 +0x47
github.com/microsoft/typescript-go/internal/checker.(*Checker).getContextualType(0xc0068cd908, 0xc005b85c50, 0x4)
	github.com/microsoft/typescript-go/internal/checker/checker.go:28328 +0x1e9
github.com/microsoft/typescript-go/internal/checker.(*Checker).GetContextualType.func1()
	github.com/microsoft/typescript-go/internal/checker/services.go:310 +0x1e
github.com/microsoft/typescript-go/internal/checker.runWithoutResolvedSignatureCaching[...](0xc0068cd908?, 0xc00382f4a0, 0xc0024134d8?)
	github.com/microsoft/typescript-go/internal/checker/services.go:365 +0x362
github.com/microsoft/typescript-go/internal/checker.runWithInferenceBlockedFromSourceNode[...](0xc0068cd908?, 0xa0bf53, 0xc0024134d8?)
	github.com/microsoft/typescript-go/internal/checker/services.go:329 +0xc7
github.com/microsoft/typescript-go/internal/checker.(*Checker).GetContextualType(0xc0059a0640?, 0xc004ea9650?, 0x24135f0?)
	github.com/microsoft/typescript-go/internal/checker/services.go:310 +0x45
github.com/microsoft/typescript-go/internal/ls.getContextualType(0xc005b85c50, 0xc007c50008?, 0xc0068cd908?, 0xc0068cd908)
	github.com/microsoft/typescript-go/internal/ls/completions.go:3026 +0x2d1
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).getCompletionData(0xc00c839410, {0x10960c8, 0xc00c839230}, 0xc0068cd908, 0xc007c50008, 0x68e, 0xc0074caf00)
	github.com/microsoft/typescript-go/internal/ls/completions.go:1727 +0x1633
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).getCompletionsAtPosition(0xc00c839410, {0x10960c8, 0xc00c839230}, 0xc007c50008, 0x68e, 0x0)
	github.com/microsoft/typescript-go/internal/ls/completions.go:383 +0x2cf
github.com/microsoft/typescript-go/internal/ls.(*LanguageService).ProvideCompletion(0xc00c839410, {0x10960c8, 0xc00c839230}, {0xc00698dc20?, 0xc00c839230?}, {0x698dc20?, 0xc0?}, 0xc000b90bb0)
	github.com/microsoft/typescript-go/internal/ls/completions.go:44 +0xc8
github.com/microsoft/typescript-go/internal/lsp.(*Server).handleCompletion(0xc000900008?, {0x10960c8?, 0xc00c839230?}, 0xc00698dc20?, 0x40b92c?)
	github.com/microsoft/typescript-go/internal/lsp/server.go:1011 +0x39
github.com/microsoft/typescript-go/internal/lsp.init.func1.registerLanguageServiceDocumentRequestHandler[...].16({0x10960c8, 0xc00c839230}, 0xc0127513b0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:617 +0x130
github.com/microsoft/typescript-go/internal/lsp.(*Server).handleRequestOrNotification(0xc0001e4008, {0x1096100?, 0xc003a22be0?}, 0xc0127513b0)
	github.com/microsoft/typescript-go/internal/lsp/server.go:501 +0x14b
github.com/microsoft/typescript-go/internal/lsp.(*Server).dispatchLoop.func1()
	github.com/microsoft/typescript-go/internal/lsp/server.go:404 +0x3a
created by github.com/microsoft/typescript-go/internal/lsp.(*Server).dispatchLoop in goroutine 18
	github.com/microsoft/typescript-go/internal/lsp/server.go:424 +0x9ad

A fix should probably just modify the existing test cases from the recent PR.</issue_description>

Comments on the Issue (you are @copilot in this section)

  • Fixes microsoft/typescript-go#2296

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot avatar Dec 09 '25 08:12 Copilot