From 5f19015e168b4acbba3cd55adab5938cec52e903 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 21 May 2026 19:28:45 +0900 Subject: [PATCH] selfhost/cmd/wcc: stamp e.type_ for N_STRUCTLIT (A.6.1.6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port head-only of cstage cmd/wcc/check.c:1161-1197 to exprtype's new N_STRUCTLIT arm: - N_IDENT lhs: scopelookupprefer → SK_TYPE sym; stamp tinfofornode(sym.decl.lhs), return that body. Mirrors cstage L1166-1173. - Synthetic type-expr lhs (e.g. `(*T){...}`): stamp tinfofornode(e.lhs), return e.lhs directly. Mirrors cstage L1174-1176. - e.lhs == nil: bail (future Hare anonymous-lit shape ww doesn't parse yet — lib/ww/parse/expr.ww:147-148 always plants the TYPE_IDENT). Field-level walk (cstage L1178-1194) stays parked behind #23 / Phase 2; field-value exprs still get their own n.type_ via the post-order dispatch at L460-489 (N_STRUCTLIT is in the kind list since A.6.0). One documented divergence from cstage: lenient on missing- struct-type / non-SK_TYPE sym (cstage L1170 errors; wwstage falls through to nil under the established scruttype L656 / A.6.1.5b N_DOT struct-miss policy). α scope per Drew (ref/hare/hare/ast/expr.ha:229-237 — Hare's struct_literal AST distinguishes named/anonymous alias; ww only parses the named form, so the hint param plumbed in A.6.0 stays unused for this arm). β/γ (hint plumbing into clet/ cassign; A.6.1.7 preempt) deferred per rule 11. Phase 1 A.6 step 6 of ~8 — Hare struct_literal surface closed; N_ARRLIT (A.6.1.7) is the genuine hint-consumer next. Verified 132/132 incl. 995_self_rebuild byte-identity. --- selfhost/cmd/w6c/main.combined.ww | 29 ++++++++++++++++++++++++++++ selfhost/cmd/wcc/check.ww | 29 ++++++++++++++++++++++++++++ selfhost/cmd/wwdump/main.combined.ww | 29 ++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 9b4b8b04..abe37332 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -8699,6 +8699,35 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; + if (k == nkind.N_STRUCTLIT) { + // A.6.1.6 — head-only stamp of the struct-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk + // (cstage L1178-1194) parked behind #23 / Phase 2 — field + // values are walked by the post-order exprtype dispatch at + // L460-489, so each field expr still gets its own n.type_. + // + // Parser at lib/ww/parse/expr.ww:147-148 always plants the + // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- + // style anonymous struct lit we don't yet parse — bail. + if (e.lhs == nil) { return nil; }; + if (e.lhs.kind == nkind.N_IDENT) { + let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *node = ms.decl.lhs; + if (tn != nil) { + e.type_ = tinfofornode(c, tn): *void; + return tn; + }; + }; }; }; + // Lenient on miss: cstage L1170 errors, wwstage falls + // through (scruttype L656 / A.6.1.5b N_DOT struct-miss). + return nil; + }; + // Synthetic type-expr (`(*T){...}` etc). Mirror cstage L1175 + // resolve_type(c, n->lhs). + e.type_ = tinfofornode(c, e.lhs): *void; + return e.lhs; + }; 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 85905dc3..16632b52 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1767,6 +1767,35 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; + if (k == nkind.N_STRUCTLIT) { + // A.6.1.6 — head-only stamp of the struct-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk + // (cstage L1178-1194) parked behind #23 / Phase 2 — field + // values are walked by the post-order exprtype dispatch at + // L460-489, so each field expr still gets its own n.type_. + // + // Parser at lib/ww/parse/expr.ww:147-148 always plants the + // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- + // style anonymous struct lit we don't yet parse — bail. + if (e.lhs == nil) { return nil; }; + if (e.lhs.kind == nkind.N_IDENT) { + let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *node = ms.decl.lhs; + if (tn != nil) { + e.type_ = tinfofornode(c, tn): *void; + return tn; + }; + }; }; }; + // Lenient on miss: cstage L1170 errors, wwstage falls + // through (scruttype L656 / A.6.1.5b N_DOT struct-miss). + return nil; + }; + // Synthetic type-expr (`(*T){...}` etc). Mirror cstage L1175 + // resolve_type(c, n->lhs). + e.type_ = tinfofornode(c, e.lhs): *void; + return e.lhs; + }; 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 30d6691d..93db3948 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -8699,6 +8699,35 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { }; return nil; }; + if (k == nkind.N_STRUCTLIT) { + // A.6.1.6 — head-only stamp of the struct-lit's overall type. + // Mirror cstage cmd/wcc/check.c:1161-1197; field-level walk + // (cstage L1178-1194) parked behind #23 / Phase 2 — field + // values are walked by the post-order exprtype dispatch at + // L460-489, so each field expr still gets its own n.type_. + // + // Parser at lib/ww/parse/expr.ww:147-148 always plants the + // TYPE_IDENT in e.lhs; e.lhs == nil would be a future Hare- + // style anonymous struct lit we don't yet parse — bail. + if (e.lhs == nil) { return nil; }; + if (e.lhs.kind == nkind.N_IDENT) { + let ms: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str); + if (ms != nil) { if (ms.skind == skind.SK_TYPE) { if (ms.decl != nil) { + let tn: *node = ms.decl.lhs; + if (tn != nil) { + e.type_ = tinfofornode(c, tn): *void; + return tn; + }; + }; }; }; + // Lenient on miss: cstage L1170 errors, wwstage falls + // through (scruttype L656 / A.6.1.5b N_DOT struct-miss). + return nil; + }; + // Synthetic type-expr (`(*T){...}` etc). Mirror cstage L1175 + // resolve_type(c, n->lhs). + e.type_ = tinfofornode(c, e.lhs): *void; + return e.lhs; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union.