Something went wrong. Try again.
Jam Programming Language jamlang.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990// Enum variants carrying a *struct* (byref aggregate) payload.//// Regression test for a codegen bug: matching `Option(SomeStruct).Some(s)`// loaded the payload into an SSA aggregate value and then handed it to a// Store, which memcpy'd *from the value* as if it were a pointer — a// malformed `memcpy(dst, %Struct val, ...)` that read a wild address and// segfaulted. Scalar payloads (ints, bools, pointers) were unaffected.// The fix makes enum-payload extraction follow the same byref convention// as Load: an aggregate payload's "value" is its storage pointer.
const { assert } = import("test");const { Option } = import("std").option;
const Point = struct { x: u32, y: u32 };
fn wrapPoint(x: u32, y: u32) Option(Point) { var p: Point = Point { x: x, y: y }; return Option(Point).Some(p);}
fn sumPoint(o: Option(Point)) u32 { match (o) { Option(Point).Some(p) { return p.x + p.y; } Option(Point).None { return 0; } } return 999;}
// Struct fields round-trip through construction + match extraction.tfn optionStructSome() { assert(sumPoint(wrapPoint(30, 12)), 42); }
// None still works for a struct-payload Option.tfn optionStructNone() { assert(sumPoint(Option(Point).None()), 0); }
// Struct payload behind a `mut` cursor parameter — the std.process// iterator shape (next(&cursor) -> Option(struct)).const Cursor = struct { i: u32, n: u32 };
fn step(c: mut Cursor) Option(Point) { if (c.i >= c.n) { return Option(Point).None(); } var p: Point = Point { x: c.i, y: 0 }; c.i = c.i + 1; return Option(Point).Some(p);}
tfn mutCursorStructPayload() { var c: Cursor = Cursor { i: 0, n: 4 }; var total: u32 = 0; var more: bool = true; while (more) { match (step(c)) { Option(Point).Some(p) { total = total + p.x; } Option(Point).None { more = false; } } } assert(total, 6); // 0 + 1 + 2 + 3}
// Struct payload containing a pointer field (mirrors a borrowed view).const Span = struct { ptr: *const[] u8, len: u64 };
tfn structPayloadWithPointer() { var s: []u8 = "hello"; var sp: Span = Span { ptr: s.ptr, len: s.len }; var got: u64 = 0; match (Option(Span).Some(sp)) { Option(Span).Some(v) { got = v.len; } Option(Span).None { got = 0; } } assert(got as u32, 5);}
// Custom (non-Option) enum with a struct-payload variant.const Pair = struct { a: u32, b: u32 };const Msg = enum { Empty, Load(Pair),};
fn evalMsg(m: Msg) u32 { match (m) { Msg.Empty { return 0; } Msg.Load(p) { return p.a * 10 + p.b; } } return 99;}
tfn customEnumStructPayloadLoad() { assert(evalMsg(Msg.Load(Pair { a: 4, b: 2 })), 42); }tfn customEnumStructPayloadEmpty() { assert(evalMsg(Msg.Empty), 0); }