ffi M5.A.next.5.2.B: generic Into(Block) impl — make-green
Adds the generic `impl Into(Block) for Closure(..$args) -> $R` in `library/modules/std/objc_block.sx` alongside the existing hand-rolled `Closure() -> void` and `Closure(bool) -> void` impls. The convert body is a single `#insert build_block_convert($args, $R);` — per-call-shape monomorphisation re-runs the builder so each closure shape gets its dedicated nested `callconv(.c)` trampoline + Block literal. The impl-mono path threads pack types through `pack_bindings[args]` and the single-type return through `type_bindings[R]`. Both need to be visible to the body's `$args` / `$R` expression-position references — the existing lowering only consulted `pack_arg_types` (set by pack-fn mono, not by tryPackImplMatch). Two small extensions: - `lowerExpr`'s `.comptime_pack_ref` arm now consults `pack_arg_types` → `pack_bindings` → `type_bindings` in order, treating a `type_bindings` hit as a single `const_type(T)` value rather than the slice form. - `resolveTypeArg` grows a `.comptime_pack_ref` arm that maps the same name through `type_bindings` so type-arg positions (e.g. inside `type_name(...)` in the builder body) resolve the bound single Type. - `type_bridge.isTypeShapedAstNode` lists `comptime_pack_ref` and `pack_index_type_expr` as type-shaped so `buildTypeBindings`'s strategy-1 explicit-arg path picks them up when calling a `$T: Type`-generic fn. `examples/177-generic-into-block.sx` flips green: a `Closure(s64, s64) -> void` (no hand-rolled impl) is converted through the generic impl, its block invoked via a typed `callconv(.c)` fn-pointer, and the closure's side effects land in the host globals. Hand-rolled impls remain for `()` and `(bool)` shapes; 5.3 deletes those once a focused test covers their behaviour through the generic path. Suite at 217/217.
This commit is contained in:
@@ -108,6 +108,20 @@ impl Into(Block) for Closure(bool) -> void {
|
||||
}
|
||||
}
|
||||
|
||||
// Generic impl: covers any closure shape not handled by the
|
||||
// hand-rolled per-signature impls above. The compiler
|
||||
// monomorphises this body per call shape; inside each mono,
|
||||
// `$args` is the bound pack of arg types and `$R` is the bound
|
||||
// return type. The `#insert` evaluates `build_block_convert` at
|
||||
// comptime and substitutes the resulting source — a nested
|
||||
// `callconv(.c)` trampoline + the Block literal that points its
|
||||
// `invoke` slot at it.
|
||||
impl Into(Block) for Closure(..$args) -> $R {
|
||||
convert :: (self: Closure(..$args) -> $R) -> Block {
|
||||
#insert build_block_convert($args, $R);
|
||||
}
|
||||
}
|
||||
|
||||
// Comptime builder for the generic `Into(Block) for Closure(..$args)
|
||||
// -> $R` impl body. Receives the closure's per-position pack types
|
||||
// (`args`, a comptime `[]Type`) and the closure's return type
|
||||
|
||||
Reference in New Issue
Block a user