selfhost/cmd/wcc: stamp e.type_ for N_STRUCTLIT (A.6.1.6)

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.
This commit is contained in:
2026-05-21 19:28:45 +09:00
parent aa73e73013
commit 5f19015e16
3 changed files with 87 additions and 0 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.