// Closure free-variable capture works through `FfiIntrinsicCall` // nodes — names referenced inside `#objc_call` / `#jni_call` / // `#jni_static_call` argument lists from inside a closure body are // recognized as captured variables and bound from the closure's env // struct at call time. `passthrough_works` is the baseline (normal // expression capture); `passthrough_via_objc_call` exercises the same // capture through an FFI intrinsic call's arg list. #import "modules/std.sx"; #import "modules/build.sx"; #import "modules/ffi/objc.sx"; passthrough_works :: (recv: *void) -> Closure(i32) -> *void { closure((d: i32) -> *void => recv) // captures `recv` — fine } passthrough_via_objc_call :: (recv: *void) -> Closure(i32) -> i64 { // Same `recv` capture, but inside `#objc_call(...)`'s arg list. closure((d: i32) -> i64 => #objc_call(i64)(recv, "hash")) } main :: () -> i32 { inline if OS == .macos { f := passthrough_works(null); p := f(0); print("ok (passthrough works) = {}\n", p == null); // Capture inside the `#objc_call` arg list. ns_object := objc_getClass("NSObject".ptr); g := passthrough_via_objc_call(ns_object); h := g(0); print("ok (passthrough via #objc_call) = {}\n", h != 0); } inline if OS != .macos { print("skipped (not macos)\n"); } 0 }