mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
Await each value of for await over an untyped array
A JavaScript array literal that mixes promises and plain values lowers as a checked-dynamic value, and for await over it took the synchronous iteration path, binding the promises themselves. It now takes the async mode of the checked-dynamic loop, which awaits each value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
4a90c59cf3
commit
ce6be86afb
@@ -9480,9 +9480,11 @@ export function lowerForOf(lowerer: Lowerer, stmt: ts.ForOfStatement): IrStmt {
|
||||
|
||||
// A CHECKED-DYNAMIC iterable (`unknown[]`, the collapsed
|
||||
// `(string | object)[]`, JSON-parsed values): a checked IteratorRecord
|
||||
// binds each yielded dyn value.
|
||||
// binds each yielded dyn value. Under `for await` (a JavaScript array
|
||||
// literal mixing promises and plain values) the async-from-sync rules
|
||||
// await each value.
|
||||
if (iterable.type.kind === "dyn") {
|
||||
return lowerForOfDyn(lowerer, stmt, iterable, labels);
|
||||
return lowerForOfDyn(lowerer, stmt, iterable, labels, stmt.awaitModifier !== undefined);
|
||||
}
|
||||
if (tupleSource === null) {
|
||||
lowerer.badType(stmt.expression, lowerer.typeOf(stmt.expression));
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6600-npm-await-mixed-array/main.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// for await over JavaScript array literals mixing promises and plain values
|
||||
// (in a dependency): every value is awaited before the body runs, a break
|
||||
// ends the loop, and a rejected element rejects the loop at that step.
|
||||
import { run } from 'mixed-awaits';
|
||||
|
||||
for (const line of await run()) console.log(line);
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function run(): Promise<string[]>;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// for await over JavaScript array literals that mix promises and plain
|
||||
// values: each value is awaited, as the async-from-sync iterator does.
|
||||
'use strict';
|
||||
async function run() {
|
||||
var out = [];
|
||||
for await (var p of [Promise.resolve('p1'), 'p2', Promise.resolve(3)]) out.push(typeof p + ':' + p);
|
||||
for await (let q of [1, Promise.resolve({ n: 2 }), null]) out.push(JSON.stringify(q));
|
||||
for await (const r of ['a', Promise.resolve('b'), 'c']) {
|
||||
if (r === 'b') break;
|
||||
out.push('r:' + r);
|
||||
}
|
||||
try {
|
||||
for await (const s of ['ok', Promise.reject(new Error('rejected element')), 'never']) out.push('s:' + s);
|
||||
} catch (error) {
|
||||
out.push(error.message);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
module.exports = { run };
|
||||
+1
@@ -0,0 +1 @@
|
||||
{ "name": "mixed-awaits", "version": "1.0.0", "main": "index.js", "types": "index.d.ts" }
|
||||
Reference in New Issue
Block a user