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

Assertion failure in method snippet completions for subclasses with multiple type parameter references #48379

Closed
DanielRosenwasser opened this issue Mar 23, 2022 · 5 comments · Fixed by #48490
Assignees
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Domain: Completion Lists The issue relates to showing completion lists in an editor Fix Available A PR has been opened for this issue

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Mar 23, 2022

Same stack trace as #45744

declare class Component<T> {
  setState(stateHandler: ((oldState: T, newState: T) => void)): void;
}

class SubComponent extends Component<{}> {
    /*$*/
}

Request snippet completions at /*$*/.

<semantic> Response received: completionInfo (1916). Request took 8 ms. Success: false . Message: Error processing request. Debug Failure. False expression.
Error: Debug Failure. False expression.
    at consumeTokenAndAdvanceScanner ([node_modules_dir]/typescript/lib/tsserver.js:145519:30)
    at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145489:33)
    at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
    at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
    at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30323:24)
    at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
    at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
    at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145496:48)
    at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
    at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
    at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30330:24)
    at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
    at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
    at [node_modules_dir]/typescript/lib/tsserver.js:145382:21
    at visitNode ([node_modules_dir]/typescript/lib/tsserver.js:30147:24)
    at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30242:21)
    at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
    at processChildNode ([node_modules_dir]/typescript/lib/tsserver.js:145449:21)
    at processChildNodes ([node_modules_dir]/typescript/lib/tsserver.js:145496:48)
    at [node_modules_dir]/typescript/lib/tsserver.js:145384:21
    at visitNodes ([node_modules_dir]/typescript/lib/tsserver.js:30152:24)
    at Object.forEachChild ([node_modules_dir]/typescript/lib/tsserver.js:30304:21)
    at processNode ([node_modules_dir]/typescript/lib/tsserver.js:145381:20)
    at formatSpanWorker ([node_modules_dir]/typescript/lib/tsserver.js:145182:17)
    at [node_modules_dir]/typescript/lib/tsserver.js:145146:140
    at Object.getFormattingScanner ([node_modules_dir]/typescript/lib/tsserver.js:143773:23)
    at Object.formatNodeGivenIndentation ([node_modules_dir]/typescript/lib/tsserver.js:145146:31)
    at [node_modules_dir]/typescript/lib/tsserver.js:131006:46
    at Object.flatMap ([node_modules_dir]/typescript/lib/tsserver.js:508:25)
    at getEntryForMemberCompletion ([node_modules_dir]/typescript/lib/tsserver.js:131004:38)
    at createCompletionEntry ([node_modules_dir]/typescript/lib/tsserver.js:130828:23)
    at getCompletionEntriesFromSymbols ([node_modules_dir]/typescript/lib/tsserver.js:131194:29)
    at completionInfoFromData ([node_modules_dir]/typescript/lib/tsserver.js:130646:17)
    at Object.getCompletionsAtPosition ([node_modules_dir]/typescript/lib/tsserver.js:130507:36)
    at Object.getCompletionsAtPosition ([node_modules_dir]/typescript/lib/tsserver.js:163069:35)
    at IpcIOSession.Session.getCompletions ([node_modules_dir]/typescript/lib/tsserver.js:174630:64)
    at Session.handlers.ts.Map.ts.getEntries._a.<computed> ([node_modules_dir]/typescript/lib/tsserver.js:173451:61)
    at [node_modules_dir]/typescript/lib/tsserver.js:175346:88
    at IpcIOSession.Session.executeWithRequestId ([node_modules_dir]/typescript/lib/tsserver.js:175337:28)
    at IpcIOSession.Session.executeCommand ([node_modules_dir]/typescript/lib/tsserver.js:175346:33)
    at IpcIOSession.Session.onMessage ([node_modules_dir]/typescript/lib/tsserver.js:175372:35)
    at process.<anonymous> ([node_modules_dir]/typescript/lib/tsserver.js:178007:31)
    at process.emit (events.js:315:20)
    at emit (internal/child_process.js:903:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:21)

That's one minimal example. The more motivating example is completion for all React class components.

interface Component<P = {}, S = {}, SS = any> { }
declare class Component<P, S> {
  setState<K extends keyof S>(
    state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
    callback?: () => void
  ): void;
}

export class Thing extends Component<{}> {
    /*$*/
}
@DanielRosenwasser DanielRosenwasser added Bug A bug in TypeScript Domain: Completion Lists The issue relates to showing completion lists in an editor Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output labels Mar 23, 2022
@DanielRosenwasser DanielRosenwasser changed the title Assertion failure in method snippet completions for subclasses from React's setState Assertion failure in method snippet completions for subclasses with multiple type parameter references Mar 23, 2022
@DanielRosenwasser DanielRosenwasser added this to the TypeScript 4.7.0 milestone Mar 23, 2022
@jakebailey
Copy link
Member

jakebailey commented Mar 28, 2022

I think I've wrapped my head around this one.

In the above example, the key is that in the real method implementation, the type var appears more than once. All of the Ts need to be converted to {}, except that all {} nodes in this tree appear to be the same object. This trips up the text change code, as when the new text (with {}) is being created, the walker stores the new positions onto the node, so that later those nodes can use the faked SourceFile with the new text. But since all of the {}s are the same node, the position ends up being wherever the last walked {} is, which breaks the invariant that a node's children actually be within its range.

@jakebailey
Copy link
Member

Hm, maybe not; I forced the node constructor to add unique IDs to each node and they are different. Back to debugging, I guess.

@jakebailey
Copy link
Member

jakebailey commented Mar 29, 2022

No, I was right initially. Here's the emitter going over the second empty type literal, but the members NodeArray is the same and already has the side-effect __pos and __end set.

image

@DanielRosenwasser
Copy link
Member Author

I wonder if this also fixes #48405 at all?

@jakebailey
Copy link
Member

That issue already has #48481 (which is unreviewed) and looks different. I'll check the test case on main and see, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Crash For flagging bugs which are compiler or service crashes or unclean exits, rather than bad output Domain: Completion Lists The issue relates to showing completion lists in an editor Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
@DanielRosenwasser @jakebailey @typescript-bot and others