From 66c4ee168bc0a403a280ff7c35075376775516ce Mon Sep 17 00:00:00 2001 From: agra Date: Sat, 30 May 2026 03:15:07 +0300 Subject: [PATCH] lang F1 6: contextually type pack-fn prefix args (mapper lambda) lowerPackFnCall lowered the runtime prefix args with no target_type, so a lambda arg (mapper: Closure(...) -> ...) could not infer its param types. Now set target_type to the param type while lowering each prefix arg. With the existing value-projection call-arg spread, mapper(..sources.get) works: the lambda is contextually typed and the projected values spread into the call. examples/211 ((a,b)=>a+b over two sources -> 42). 246 + unit green. --- examples/211-mapper-projection-spread.sx | 18 ++++++++++++++++++ src/ir/lower.zig | 6 ++++++ .../expected/211-mapper-projection-spread.exit | 1 + .../expected/211-mapper-projection-spread.txt | 1 + 4 files changed, 26 insertions(+) create mode 100644 examples/211-mapper-projection-spread.sx create mode 100644 tests/expected/211-mapper-projection-spread.exit create mode 100644 tests/expected/211-mapper-projection-spread.txt diff --git a/examples/211-mapper-projection-spread.sx b/examples/211-mapper-projection-spread.sx new file mode 100644 index 0000000..9121340 --- /dev/null +++ b/examples/211-mapper-projection-spread.sx @@ -0,0 +1,18 @@ +// Phase 6 — `mapper(..sources.value)`: project a method over a pack and spread +// the results into a closure call. The mapper lambda's params are contextually +// typed from the `Closure(...)` parameter even though `apply` is a pack-fn. + +#import "modules/std.sx"; + +VL :: protocol(T: Type) { get :: () -> T; } +IntCell :: struct { v: s64; } +impl VL(s64) for IntCell { get :: (self: *IntCell) -> s64 => self.v; } + +apply :: (mapper: Closure(s64, s64) -> s64, ..sources: VL) -> s64 { + return mapper(..sources.get); // (a, b) => a + b applied to (s0.get(), s1.get()) +} + +main :: () -> s32 { + print("{}\n", apply((a, b) => a + b, IntCell.{ v = 40 }, IntCell.{ v = 2 })); // 42 + 0; +} diff --git a/src/ir/lower.zig b/src/ir/lower.zig index cd2ac80..167d435 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -9195,7 +9195,13 @@ pub const Lowering = struct { if (isPackParam(p)) break; if (ri >= call_node.args.len) break; if (!p.is_comptime) { + // Contextually type the arg from the param (so a lambda arg + // `(x) => …` takes its param types from a `Closure(...)` param). + const saved_tt = self.target_type; + const pty = self.resolveParamType(&p); + if (pty != .unresolved) self.target_type = pty; args.append(self.alloc, self.lowerExpr(call_node.args[ri])) catch return self.builder.constInt(0, .void); + self.target_type = saved_tt; } ri += 1; } diff --git a/tests/expected/211-mapper-projection-spread.exit b/tests/expected/211-mapper-projection-spread.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/expected/211-mapper-projection-spread.exit @@ -0,0 +1 @@ +0 diff --git a/tests/expected/211-mapper-projection-spread.txt b/tests/expected/211-mapper-projection-spread.txt new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/tests/expected/211-mapper-projection-spread.txt @@ -0,0 +1 @@ +42