fix(parser): disallow in expressions in using for-loop initializers (#26490)

Reject invalid initializers such as `for (using x = a in b;;);` by parsing `using` and `await using` declarations with `Context::In` disabled, matching ordinary for-loop declarations. Restore the outer context afterward so parenthesized `in` expressions and the remaining loop expressions keep their existing behavior.
This commit is contained in:
camc314 committed 2026-09-09 14:03:17 +00:00
1 parent 5983db126d
commit 5501e86429
10 files changed
+64 -14

No files matched your search

+2 -1
View File
@@ -536,7 +536,8 @@ impl<'a, C: Config> ParserImpl<'a, C> {
parenthesis_opening_span: Span,
r#await: bool,
) -> Statement<'a> {
let using_decl = self.parse_using_declaration(StatementContext::For);
let using_decl =
self.context_remove(Context::In, |p| p.parse_using_declaration(StatementContext::For));
if matches!(self.cur_kind(), Kind::In) {
if using_decl.kind.is_await() {
@@ -0,0 +1,3 @@
async function f() {
for (await using x = a in b;;);
}
@@ -0,0 +1 @@
for (using x = a in b;;);
@@ -0,0 +1,11 @@
for (using x = (a in b); a in b; a in b) {
a in b;
}
a in b;
async function f() {
for (await using x = (a in b); a in b; a in b) {
a in b;
}
a in b;
}
+2 -2
View File
@@ -1,3 +1,3 @@
codegen_misc Summary:
AST Parsed : 96/96 (100.00%)
Positive Passed: 96/96 (100.00%)
AST Parsed : 97/97 (100.00%)
Positive Passed: 97/97 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
formatter_misc Summary:
AST Parsed : 96/96 (100.00%)
Positive Passed: 96/96 (100.00%)
AST Parsed : 97/97 (100.00%)
Positive Passed: 97/97 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
lexer_misc Summary:
AST Parsed : 294/294 (100.00%)
Positive Passed: 294/294 (100.00%)
AST Parsed : 297/297 (100.00%)
Positive Passed: 297/297 (100.00%)
+37 -3
View File
@@ -1,7 +1,7 @@
parser_misc Summary:
AST Parsed : 96/96 (100.00%)
Positive Passed: 96/96 (100.00%)
Negative Passed: 198/198 (100.00%)
AST Parsed : 97/97 (100.00%)
Positive Passed: 97/97 (100.00%)
Negative Passed: 200/200 (100.00%)
× Cannot assign to 'arguments' in strict mode
╭─[misc/fail/arguments-eval-ambient.ts:2:13]
@@ -551,6 +551,40 @@ Negative Passed: 198/198 (100.00%)
· ──
╰────
× The left-hand side of a for...in statement cannot be an await using declaration.
╭─[misc/fail/for-await-using-in-initializer.js:2:8]
1 │ async function f() {
2 │ for (await using x = a in b;;);
· ─────────────────
3 │ }
╰────
help: Did you mean to use a for...of statement?
× Expected `)` but found `;`
╭─[misc/fail/for-await-using-in-initializer.js:2:30]
1 │ async function f() {
2 │ for (await using x = a in b;;);
· ┬ ┬
· │ ╰── `)` expected
· ╰── Opened here
3 │ }
╰────
× The left-hand side of a for...in statement cannot be an using declaration.
╭─[misc/fail/for-using-in-initializer.js:1:6]
1 │ for (using x = a in b;;);
· ───────────
╰────
help: Did you mean to use a for...of statement?
× Expected `)` but found `;`
╭─[misc/fail/for-using-in-initializer.js:1:22]
1 │ for (using x = a in b;;);
· ┬ ┬
· │ ╰── `)` expected
· ╰── Opened here
╰────
× A 'get' accessor must not have any formal parameters.
╭─[misc/fail/getter-rest-parameter.ts:1:16]
1 │ class C { get x(...args) {} }
+2 -2
View File
@@ -1,6 +1,6 @@
semantic_misc Summary:
AST Parsed : 96/96 (100.00%)
Positive Passed: 92/96 (95.83%)
AST Parsed : 97/97 (100.00%)
Positive Passed: 93/97 (95.88%)
semantic Error: tasks/coverage/misc/pass/declare-let-private.ts
Bindings mismatch:
after transform: ScopeId(0): ["private"]
@@ -1,3 +1,3 @@
transformer_misc Summary:
AST Parsed : 96/96 (100.00%)
Positive Passed: 96/96 (100.00%)
AST Parsed : 97/97 (100.00%)
Positive Passed: 97/97 (100.00%)