Skip to content

Invalid code generation for top-level await with newline (expression duplicated) #39186

Closed

Description

@evanw

TypeScript Version: Nightly

Search Terms: top-level await newline duplicate duplicated

Code

export let foo = () => {
  console.log('called')
  return Promise.resolve(123)
}
export let bar = await
  foo()

Expected behavior:

The generated code should only call foo() once.

Actual behavior:

The generated code calls foo() twice:

export let foo = () => {
    console.log('called');
    return Promise.resolve(123);
};
export let bar = await foo();
foo();

This may lead to subtle correctness bugs. This only happens when there's a newline between the await keyword and the awaited expression. This also only happens for top-level await. Enclosing the await in an async function makes the bug disappear.

Playground Link: link

Related Issues:

Activity

  1. RyanCavanaugh commented on Jun 22, 2020

    @RyanCavanaugh
    Member

    Ron Buckton (@rbuckton) big emit bug here

  2. rbuckton commented on Jun 22, 2020

    @rbuckton
    Contributor

    Hmm. Not an emit bug, but a bug in the reparse for top-level await due to newline handling probably. I'll investigate.

  3. rbuckton commented on Jun 22, 2020

    @rbuckton
    Contributor

    Ryan Cavanaugh (@RyanCavanaugh):

    There's a "quick solution" and a "good solution":

    • quick solution: Limit the reparse to the extent of the original expression. This will prevent duplication but would result in an expression expected error following the await. This is undesirable, but is also no worse than the behavior in 3.9.
    • good solution: When reparsing, if the extent of the new expression is larger than the original expression, we must also reparse the statement that follows starting at the end position of the new expression. This may take some additional time to implement.

    I'm investigating the "good solution" currently, and if it looks like it will take more than the rest of the day to implement I would advise we implement the "quick solution" for the 4.0 beta.

  4. RyanCavanaugh commented on Jun 23, 2020

    @RyanCavanaugh
    Member

    If we already shipped this in 3.9 then I'm OK waiting for the "good solution"

  5. rbuckton commented on Jun 23, 2020

    @rbuckton
    Contributor

    This wasn't in 3.9, its is a bug in the change in 4.0 to reparse await in the top-level of a module.

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions