mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-04 08:04:37 +08:00
Lower a discarded undefined catch handler
`Promise<void>.catch(() => undefined)` tripped the IR validator's bare-unitLit rule: the handler body lowered as a bare expression, and `undefined` has no standalone IR value. The handler's value is discarded, so lower the body as a statement — the same rule a discarded `undefined;` statement already follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ed90c10fce
commit
279d42e562
@@ -6908,7 +6908,10 @@ export function lowerPromiseMethodCall(
|
||||
if (ts.isBlock(hb)) {
|
||||
catchBody = lowerer.lowerStmts(hb.statements.nodes);
|
||||
} else if (R.kind === "void") {
|
||||
catchBody = [{ kind: "exprStmt", expr: lowerer.lowerExpr(hb), loc: locOf(hb) }];
|
||||
// The handler's value is discarded, so the body lowers as a
|
||||
// statement: `() => undefined` is a pure no-op (a bare unit
|
||||
// literal has no IR value), not an expression to evaluate.
|
||||
catchBody = [lowerer.lowerExprStatement(hb)];
|
||||
} else {
|
||||
// Bare-expression handler: `(e) => v` (promise results flatten
|
||||
// through the async-return path, like any `return v`).
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// `Promise<void>.catch(() => undefined)` — the handler's value is
|
||||
// discarded and the recovered promise settles as void. The handler runs
|
||||
// exactly once, and the chain continues on the next turn whether the
|
||||
// receiver fulfilled or rejected.
|
||||
|
||||
const ok: Promise<void> = Promise.resolve();
|
||||
const bad: Promise<void> = Promise.reject(new Error("boom"));
|
||||
|
||||
ok.catch(() => undefined).then(() => console.log("fulfilled recovered"));
|
||||
|
||||
bad
|
||||
.catch(() => {
|
||||
console.log("rejected recovered");
|
||||
})
|
||||
.then(() => console.log("rejected continued"));
|
||||
|
||||
let runs = 0;
|
||||
|
||||
function recover(): Promise<void> {
|
||||
runs++;
|
||||
return runs % 2 === 1 ? Promise.reject(new Error("odd")) : Promise.resolve();
|
||||
}
|
||||
|
||||
async function run(): Promise<void> {
|
||||
await recover().catch(() => undefined);
|
||||
console.log("awaited recover", runs);
|
||||
await recover().catch(() => undefined);
|
||||
console.log("awaited recover", runs);
|
||||
}
|
||||
|
||||
void run().then(() => console.log("done"));
|
||||
Reference in New Issue
Block a user