// Phase 6 — `c.sources = (..sources)`: materialize a pack into a // protocol-typed tuple field, erasing each concrete pack element to the field's // protocol slot. The pack `..sources: VL` holds concrete cells; `(..sources)` // into a `(..VL(Ts))` field `xx`-erases each to its `VL(Ti)` value. #import "modules/std.sx"; VL :: protocol(T: Type) { get :: () -> T; } IntCell :: struct { v: i64; } StrCell :: struct { s: string; } impl VL(i64) for IntCell { get :: (self: *IntCell) -> i64 => self.v; } impl VL(string) for StrCell { get :: (self: *StrCell) -> string => self.s; } Combined :: struct($R: Type, ..$Ts: []Type) { sources: (..VL(Ts)); value: $R; } build :: (..sources: VL) -> void { c : Combined(i64, ..sources.T) = ---; c.sources = (..sources); // pack → tuple, per-element erase print("{} {}\n", c.sources.0.get(), c.sources.1.get()); } main :: () -> i32 { build(IntCell.{ v = 10 }, StrCell.{ s = "hi" }); // 10 hi 0 }