Skip to content

Top-level await reparse keeps statements it already consumed when it reaches the end of the file #64999

Open

Description

@roninjin10

🔎 Search Terms

top-level await, reparse, reparseTopLevelAwait, overlapping statements, parse tree, sibling

🕗 Version & Regression Information

  • TypeScript 7 at main 4a4b24d (the Go parser).
  • TypeScript 6.0.3 also keeps overlapping statements for this input: its ExpressionStatement [26, 28) starts before the statement before it ends at 37.

⏯ Playground Link

Not applicable: the problem is in the parse tree's node positions.

💻 Code

export {}; await + f(const 0 await !x

🙁 Actual behavior

The source file's statements are ExportDeclaration [0, 10), ExpressionStatement [10, 37) and ExpressionStatement [36, 37). The last one starts before the previous one ends: x is parsed twice, once inside the reparsed await + f(...) statement and once as a statement of its own.

In a module, reparseTopLevelAwait reparses the statements that may contain await in an await context, and a reparsed statement can read past its span. When the reparse reaches the end of the file, the original statements after the last span it advanced to are still copied into the new statement list.

🙂 Expected behavior

No statement starts before the end of the statement before it: once the reparse reaches the end of the file, no original statement is left to copy.

Additional information about the issue

Found by fuzzing the parser of a fork of this repository with a sibling-order invariant (each node starts at or after the end of its previous sibling). A fix with a regression test is in #64993.

This report was drafted with Claude Code (Claude Opus 5.5).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: ParserThe parser didn't handle the syntax correctly

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions