diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index abe37332..8ced2192 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -8728,6 +8728,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; + if (k == nkind.N_ARRLIT) { + // A.6.1.7 — head-only stamp of the array-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, + // skip the `...` repeat sentinel (parse/expr.ww:101-105), + // first-element-wins for the elem type, count non-skipped + // elements, synthesize an N_TARRAY{elt, INTLIT count}. Empty + // list defaults to `[0]i32` per cstage L1209. Per-element + // stamps still fire via the post-order dispatch at L460-489 + // (N_ARRLIT is in the kind list since A.6.0); the re-walk in + // the loop below is tinfocache-idempotent (L467). + // + // Documented cstage divergence: cstage L1206 applies + // type_default to lift untyped_int → i32 etc; wwstage stamps + // the raw exprtype result, matching the alloc-value-form + // precedent at L1509. Consumers default-type via the declared + // `let` slot until A.6.3 lands. Mixed-type elements follow + // cstage first-element-wins; no unify check (future scope). + let elt: *node = nil; + let count: u64 = 0u64; + let it: *node = e.list; + for (it != nil) { + let skip: bool = false; + if (it.kind == nkind.N_FIELD) { + if (streq(it.str, "...")) { skip = true; }; + }; + if (!skip) { + let t: *node = exprtype(c, it, nil); + if (elt == nil) { elt = t; }; + count += 1u64; + }; + it = it.next; + }; + if (elt == nil) { elt = mktname(c, "i32"); }; + let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + arr.lhs = elt; + let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + cn.uval = count; + arr.rhs = cn; + e.type_ = tinfofornode(c, arr): *void; + return arr; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index 16632b52..9194d9d3 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1796,6 +1796,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; + if (k == nkind.N_ARRLIT) { + // A.6.1.7 — head-only stamp of the array-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, + // skip the `...` repeat sentinel (parse/expr.ww:101-105), + // first-element-wins for the elem type, count non-skipped + // elements, synthesize an N_TARRAY{elt, INTLIT count}. Empty + // list defaults to `[0]i32` per cstage L1209. Per-element + // stamps still fire via the post-order dispatch at L460-489 + // (N_ARRLIT is in the kind list since A.6.0); the re-walk in + // the loop below is tinfocache-idempotent (L467). + // + // Documented cstage divergence: cstage L1206 applies + // type_default to lift untyped_int → i32 etc; wwstage stamps + // the raw exprtype result, matching the alloc-value-form + // precedent at L1509. Consumers default-type via the declared + // `let` slot until A.6.3 lands. Mixed-type elements follow + // cstage first-element-wins; no unify check (future scope). + let elt: *node = nil; + let count: u64 = 0u64; + let it: *node = e.list; + for (it != nil) { + let skip: bool = false; + if (it.kind == nkind.N_FIELD) { + if (streq(it.str, "...")) { skip = true; }; + }; + if (!skip) { + let t: *node = exprtype(c, it, nil); + if (elt == nil) { elt = t; }; + count += 1u64; + }; + it = it.next; + }; + if (elt == nil) { elt = mktname(c, "i32"); }; + let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + arr.lhs = elt; + let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + cn.uval = count; + arr.rhs = cn; + e.type_ = tinfofornode(c, arr): *void; + return arr; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 93db3948..2174c258 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -8728,6 +8728,47 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, e.lhs): *void; return e.lhs; }; + if (k == nkind.N_ARRLIT) { + // A.6.1.7 — head-only stamp of the array-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1198-1211: walk elements, + // skip the `...` repeat sentinel (parse/expr.ww:101-105), + // first-element-wins for the elem type, count non-skipped + // elements, synthesize an N_TARRAY{elt, INTLIT count}. Empty + // list defaults to `[0]i32` per cstage L1209. Per-element + // stamps still fire via the post-order dispatch at L460-489 + // (N_ARRLIT is in the kind list since A.6.0); the re-walk in + // the loop below is tinfocache-idempotent (L467). + // + // Documented cstage divergence: cstage L1206 applies + // type_default to lift untyped_int → i32 etc; wwstage stamps + // the raw exprtype result, matching the alloc-value-form + // precedent at L1509. Consumers default-type via the declared + // `let` slot until A.6.3 lands. Mixed-type elements follow + // cstage first-element-wins; no unify check (future scope). + let elt: *node = nil; + let count: u64 = 0u64; + let it: *node = e.list; + for (it != nil) { + let skip: bool = false; + if (it.kind == nkind.N_FIELD) { + if (streq(it.str, "...")) { skip = true; }; + }; + if (!skip) { + let t: *node = exprtype(c, it, nil); + if (elt == nil) { elt = t; }; + count += 1u64; + }; + it = it.next; + }; + if (elt == nil) { elt = mktname(c, "i32"); }; + let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0); + arr.lhs = elt; + let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0); + cn.uval = count; + arr.rhs = cn; + e.type_ = tinfofornode(c, arr): *void; + return arr; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union.