selfhost/cmd/wcc: stamp e.type_ for N_RECV (A.6.2.0d)

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.
This commit is contained in:
2026-05-21 21:10:58 +09:00
parent 4e75285a0b
commit 48c758bbe7
3 changed files with 48 additions and 0 deletions

View File

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

View File

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

View File

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