diff --git a/examples/177-generic-into-block.sx b/examples/177-generic-into-block.sx new file mode 100644 index 0000000..8344a29 --- /dev/null +++ b/examples/177-generic-into-block.sx @@ -0,0 +1,37 @@ +// FFI plan step 5.2 — generic `Into(Block) for Closure(..$args) -> +// $R` impl. One impl in stdlib covers every closure shape; the +// compiler monomorphises the impl body per call shape and emits a +// dedicated `__invoke` `callconv(.c)` trampoline + Block literal +// (via `#insert build_block_convert($args, $R);`). +// +// This test exercises a closure shape (`Closure(s64, s64) -> void`) +// that has NO hand-rolled `Into(Block)` impl in +// `library/modules/std/objc_block.sx`. Before step 5.2 lands, +// `xx cl : Block` errors out with the "no Into(Block) for +// cl_s64_s64__void" focused diagnostic. After the generic impl +// lands, the same call resolves through the pack-shaped impl and +// the per-shape trampoline ferries control back to the sx closure. +// +// The block is invoked directly through `b.invoke` (a typed +// `callconv(.c)` fn-pointer) — the same shape the Apple Block +// runtime calls when a UIKit/Foundation API hands the block back +// to its registered invoke. + +#import "modules/std.sx"; +#import "modules/std/objc_block.sx"; + +g_a: s64 = 0; +g_b: s64 = 0; + +main :: () -> s32 { + cl := (a: s64, b: s64) => { g_a = a; g_b = b; }; + blk : Block = xx cl; + + invoke_fn : (*Block, s64, s64) -> void callconv(.c) = xx blk.invoke; + invoke_fn(@blk, 10, 20); + + if g_a != 10 { print("FAIL: g_a={}\n", g_a); return 1; } + if g_b != 20 { print("FAIL: g_b={}\n", g_b); return 1; } + print("generic-into-block ok: a={} b={}\n", g_a, g_b); + 0; +} diff --git a/tests/expected/177-generic-into-block.exit b/tests/expected/177-generic-into-block.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/expected/177-generic-into-block.exit @@ -0,0 +1 @@ +0 diff --git a/tests/expected/177-generic-into-block.txt b/tests/expected/177-generic-into-block.txt new file mode 100644 index 0000000..7658721 --- /dev/null +++ b/tests/expected/177-generic-into-block.txt @@ -0,0 +1 @@ +generic-into-block ok: a=10 b=20