fix(parser): report for-await in non-async functions (#24855)

## Summary

- report invalid `for await` loops inside non-async functions immediately, including when an unambiguous source later resolves to a module
- update the TypeScript parser conformance snapshot with the newly reported diagnostics

## Root cause

The parser deferred every `for await` context error in unambiguous sources as a script-only error. When later `export` syntax resolved the source as a module, it discarded that deferred error even when the loop was nested inside a non-async function, where `await` is never permitted.
This commit is contained in:
camc314 committed 2026-07-23 17:58:55 +00:00
1 parent 99d263b123
commit ffcc33a676
2 files changed
+73 -3

No files matched your search

+10 -3
View File
@@ -355,9 +355,16 @@ impl<'a, C: Config> ParserImpl<'a, C> {
// [+Await]
let r#await = if self.at(Kind::Await) {
if !self.ctx.has_await() {
// For `ModuleKind::Unambiguous`, defer the error until we know whether
// this is a Module (where for-await is valid at top-level) or Script.
self.error_on_script(diagnostics::await_expression(self.cur_token().span()));
let error = diagnostics::await_expression(self.cur_token().span());
if self.ctx.has_top_level() {
// For `ModuleKind::Unambiguous`, defer the error until we know whether
// this is a Module (where for-await is valid at top-level) or Script.
self.error_on_script(error);
} else {
// A module only permits await at top level, so an await loop inside a
// non-async function is always invalid.
self.error(error);
}
}
self.bump_any();
true
@@ -3117,6 +3117,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:4:7]
3 │ function normalFunc(p: Promise<number>) {
4 │ for await (const _ of []);
· ─────
5 │ return await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:5:10]
4 │ for await (const _ of []);
@@ -3126,6 +3135,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:9:7]
8 │ export function exportedFunc(p: Promise<number>) {
9 │ for await (const _ of []);
· ─────
10 │ return await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:10:10]
9 │ for await (const _ of []);
@@ -3135,6 +3153,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:14:7]
13 │ const functionExpression = function(p: Promise<number>) {
14 │ for await (const _ of []);
· ─────
15 │ await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:15:3]
14 │ for await (const _ of []);
@@ -3144,6 +3171,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:19:7]
18 │ const arrowFunc = (p: Promise<number>) => {
19 │ for await (const _ of []);
· ─────
20 │ return await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:20:10]
19 │ for await (const _ of []);
@@ -3153,6 +3189,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:24:7]
23 │ function* generatorFunc(p: Promise<number>) {
24 │ for await (const _ of []);
· ─────
25 │ yield await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:25:9]
24 │ for await (const _ of []);
@@ -3162,6 +3207,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:30:9]
29 │ constructor(p: Promise<number>) {
30 │ for await (const _ of []);
· ─────
31 │ await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:31:5]
30 │ for await (const _ of []);
@@ -3171,6 +3225,15 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/types/wit
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:34:7]
33 │ method(p: Promise<number>) {
34 │ for await (const _ of []);
· ─────
35 │ await p;
╰────
help: Either remove this `await` or add the `async` keyword to the enclosing function
× `await` is only allowed within async functions and at the top levels of modules
╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:35:5]
34 │ for await (const _ of []);