Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/compiler/src/ir/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6074,6 +6074,14 @@ export function moduleUsesDynAsync(mod: IrModule): boolean {
found = true;
return;
}
// Promise values crossing the checked-dynamic boundary are boxed by
// emit-walkers through scr_dyn_new_promise_adapting(). That constructor
// lives in scr_async_dyn.c, so promise-typed IR must pull that TU in even

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The moduleUsesDynAsync() promise gate matches every promise-typed IR node, over-linking scr_async_dyn.c into fully-static async programs that never box a promise to dyn.

Fix on Vercel

// when the program never awaits a dyn value.
if (node.type !== undefined && node.type.kind === "promise") {
found = true;
return;
}
for (const key of Object.keys(v)) visit((v as Record<string, unknown>)[key]);
};
visit(mod);
Expand Down
10 changes: 10 additions & 0 deletions tests/harness/island.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,16 @@ console.log(__island_eval("Promise.reject(new TypeError('island second')); 'arme
expect(r.stderr).toBe("Unhandled promise rejection: RangeError: static first\n");
});

test("links the dynamic promise adapter for typed promises crossing a dynamic callback", async () => {
await build(
"typed-promise-dynamic-boundary",
`async function typed(): Promise<number> { return 1; }
function invoke(fn: () => unknown): unknown { return fn(); }
console.log(invoke(typed));
`,
);
});

test("--dynamic does not change emitted C for island-free programs", async () => {
const source = `function greet(who: string): string {
return "hello " + who;
Expand Down