Skip to content

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

Closed

Description

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<{}> {
    /*$*/
}

Activity

  1. added
    BugA bug in TypeScript
    Domain: LS: Completion ListsThe issue relates to showing completion lists in an editor
    CrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad output
    on Mar 23, 2022
  2. 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[/+] on Mar 23, 2022
  3. jakebailey commented on Mar 28, 2022

    @jakebailey
    Member

    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.

  4. jakebailey commented on Mar 28, 2022

    @jakebailey
    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.

  5. jakebailey commented on Mar 29, 2022

    @jakebailey
    Member

    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

  6. DanielRosenwasser commented on Mar 30, 2022

    @DanielRosenwasser
    MemberAuthor

    I wonder if this also fixes #48405 at all?

  7. jakebailey commented on Mar 30, 2022

    @jakebailey
    Member

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

  8. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptCrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputDomain: LS: Completion ListsThe issue relates to showing completion lists in an editorFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions