// Phase 6 — pack-spread in a parameterized-type's arg list: // `Combined($R, ..sources.T)`. Inside a pack-fn, `..sources.T` projects each // source's protocol type-arg and spreads them into the generic struct's pack // type-param `..$Ts`, so `Combined(s64, ..sources.T)` for a single `VL(s64)` // source instantiates `Combined(s64, s64)` (field `sources: (VL(s64))`). #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; } Combined :: struct($R: Type, ..$Ts: []Type) { sources: (..VL(Ts)); value: $R; } make :: (..sources: VL) -> s64 { c : Combined(s64, ..sources.T) = ---; // instantiate with the spread type-arg c.sources.0 = xx sources[0]; // erase the concrete source to VL(s64) return c.sources.0.get(); } main :: () -> s32 { print("{}\n", make(IntCell.{ v = 7 })); // 7 0; }