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.