From 48c758bbe7840295b30bd9358e07719ae548c2f8 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 21 May 2026 21:10:58 +0900 Subject: [PATCH] selfhost/cmd/wcc: stamp e.type_ for N_RECV (A.6.2.0d) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port head-only of cstage cmd/wcc/check.c:1230-1236 to exprtype's new N_RECV arm. Peel alias on the channel base; `chan T` → T. N_TCHAN element lives in .lhs (cstage ww.h:279, ww typeeqast L585). One documented divergence: cstage L1234 errors on a non-chan base; wwstage returns nil under the lenient-on-miss policy (scruttype L656 / A.6.1.5b N_DOT precedent). A.6.2 step 4 of 8 (γ order). Same shape as A.6.2.0a N_SLICE scaffold — precedent-consistent. `make test-unit` green; full `make test` batched per option B. --- selfhost/cmd/w6c/main.combined.ww | 16 ++++++++++++++++ selfhost/cmd/wcc/check.ww | 16 ++++++++++++++++ selfhost/cmd/wwdump/main.combined.ww | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 23656c27..678a94b2 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -8874,6 +8874,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, tt): *void; return tt; }; + if (k == nkind.N_RECV) { + // A.6.2.0d — head-only stamp of the receive expression's + // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 + // N_RECV: peel alias on the channel base; chan T → T. + // Documented cstage divergence: cstage L1234 errors on a + // non-chan base; wwstage returns nil (lenient on miss), + // matching scruttype L656 / A.6.1.5b N_DOT precedent. + let basetn: *node = exprtype(c, e.lhs, nil); + let bu: *node = resolvealias(c, unwrapbang(basetn)); + if (bu == nil) { return nil; }; + if (bu.kind == nkind.N_TCHAN) { + e.type_ = tinfofornode(c, bu.lhs): *void; + return bu.lhs; + }; + return nil; + }; 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 73069c15..1b19efe1 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1910,6 +1910,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, tt): *void; return tt; }; + if (k == nkind.N_RECV) { + // A.6.2.0d — head-only stamp of the receive expression's + // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 + // N_RECV: peel alias on the channel base; chan T → T. + // Documented cstage divergence: cstage L1234 errors on a + // non-chan base; wwstage returns nil (lenient on miss), + // matching scruttype L656 / A.6.1.5b N_DOT precedent. + let basetn: *node = exprtype(c, e.lhs, nil); + let bu: *node = resolvealias(c, unwrapbang(basetn)); + if (bu == nil) { return nil; }; + if (bu.kind == nkind.N_TCHAN) { + e.type_ = tinfofornode(c, bu.lhs): *void; + return bu.lhs; + }; + return nil; + }; 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 b2adafb4..6352b51a 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -8874,6 +8874,22 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { e.type_ = tinfofornode(c, tt): *void; return tt; }; + if (k == nkind.N_RECV) { + // A.6.2.0d — head-only stamp of the receive expression's + // overall type. Mirrors cstage cmd/wcc/check.c:1230-1236 + // N_RECV: peel alias on the channel base; chan T → T. + // Documented cstage divergence: cstage L1234 errors on a + // non-chan base; wwstage returns nil (lenient on miss), + // matching scruttype L656 / A.6.1.5b N_DOT precedent. + let basetn: *node = exprtype(c, e.lhs, nil); + let bu: *node = resolvealias(c, unwrapbang(basetn)); + if (bu == nil) { return nil; }; + if (bu.kind == nkind.N_TCHAN) { + e.type_ = tinfofornode(c, bu.lhs): *void; + return bu.lhs; + }; + return nil; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union.