// Closure capture analysis doesn't trace into the `FfiIntrinsicCall` // AST node — identifiers used inside `#objc_call` / `#jni_call` / // `#jni_static_call` from a closure body aren't recognized as // captured variables. Surfaced when writing `ffi-objc-call-09-in- // construct.sx`. // // Reduced repro: capture in a closure body works fine for // "normal" expressions (see `passthrough_works`), but the same // capture inside `#objc_call`'s arg list trips // "unresolved: 'recv'" (see `passthrough_via_objc_call` — would // fail at parse time, so it's commented out). // // Likely fix: in the closure free-variable analyzer (sema.zig / // lower.zig), add a recursive arm for `ffi_intrinsic_call` that // visits `return_type` + every `args[i]` the same way the `.call` // arm walks `callee` + `args`. #import "modules/std.sx"; #import "modules/compiler.sx"; passthrough_works :: (recv: *void) -> Closure(s32) -> *void { closure((d: s32) -> *void => recv); // captures `recv` — fine } // passthrough_via_objc_call :: (recv: *void) -> Closure(s32) -> s64 { // // Same `recv` capture, but inside `#objc_call(...)`: // // error: unresolved: 'recv' // closure((d: s32) -> s64 => #objc_call(s64)(recv, "hash")); // } main :: () -> s32 { inline if OS == .macos { f := passthrough_works(null); p := f(0); print("ok (passthrough works) = {}\n", p == null); } inline if OS != .macos { print("skipped (not macos)\n"); } 0; }