Fix completion crash after closing bracket in contextually-typed array literals
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
KindCloseBracketTokencase ingetContextualType()to returnnilimmediately—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 +0x9adA 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.