From a52126b87117d472dec01509b3e9309e206d3555 Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Thu, 8 Oct 2026 17:40:35 -0500 Subject: [PATCH] Fix native bootstrap callback narrowing - Check callback IR shapes before selecting the fast path. - Align the emitter contract with inline cycle deallocation. --- .../src/frontend/lowering/containers/array-callbacks.ts | 8 ++++++-- tests/harness/self-hosting-llvm-emitter-cases.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/compiler/src/frontend/lowering/containers/array-callbacks.ts b/packages/compiler/src/frontend/lowering/containers/array-callbacks.ts index 00847a558..87b00589a 100644 --- a/packages/compiler/src/frontend/lowering/containers/array-callbacks.ts +++ b/packages/compiler/src/frontend/lowering/containers/array-callbacks.ts @@ -416,8 +416,12 @@ function withFastCallback(fn: IrFunction, fastT: CallbackType | null, elem: IrTy return null; const at = e.args.findIndex(isValueRead); if (at < 0) return null; - const read = e.args[at] as IrExpr & { kind: "ternary" }; - const state = (read.cond as IrExpr & { kind: "bin" }).left as IrExpr & { kind: "arrayState" }; + const read = e.args[at]!; + if (read.kind !== "ternary") return null; + const condition = read.cond; + if (condition.kind !== "bin") return null; + const state = condition.left; + if (state.kind !== "arrayState") return null; const fastArgs = e.args.slice(); fastArgs[at] = { kind: "arrayGet", diff --git a/tests/harness/self-hosting-llvm-emitter-cases.ts b/tests/harness/self-hosting-llvm-emitter-cases.ts index 8b3b00c96..8db8b76b5 100644 --- a/tests/harness/self-hosting-llvm-emitter-cases.ts +++ b/tests/harness/self-hosting-llvm-emitter-cases.ts @@ -62,7 +62,7 @@ export function llvmEmitterCases(): LlvmEmitterCase[] { "@scr_str_release", "@scr_arr_release", ); - find("recursive record trace and teardown").contains.push("@scr_cyc_alloc", "@scr_cyc_free"); + find("recursive record trace and teardown").contains.push("@scr_cyc_alloc", "@scr_cyc_live"); find("closure capture boxes").contains.push("@sc_retain_box", "@scr_closure_new"); find("synchronous callback environment").contains.push( "alloca { %ScrClosure, [1 x ptr] }",