selfhost/cmd/wcc: stamp e.type_ for N_SLICE (A.6.2.0a)

Port head-only of cstage cmd/wcc/check.c:1214-1228 to exprtype's
new N_SLICE arm. Four base shapes:

  - N_TARRAY → synthesize N_TSLICE{lhs=elem} (cstage L1219).
  - N_TSLICE → return basetn (pre-peel, matches cstage `base`
    not `u`; L1221).
  - N_TNAME("str") → mktname("str") (matches cstage's `ty_str`
    canonical singleton, L1223).
  - N_TPTR with non-nil sub → synthesize N_TSLICE{lhs=sub}
    (L1225, Hare-faithful slice-of-elem from pointer-to-elem).

Slice bounds (e.rhs start, e.cond end) are already walked by
resolvewalk L406-408 + post-order dispatch L460-489 — typical
N_INTLIT/N_IDENT/N_BIN are in the dispatch list; this arm does
not double-walk.

One documented divergence from cstage: lenient on non-sliceable
base (cstage L1227 errs; wwstage returns nil under the established
scruttype L656 / A.6.1.5b N_DOT struct-miss precedent).

A.6.2 step 1 of 8 (γ scope per Drew, 2026-05-21) — gap-sweep
per-kind first, post-checker assertion last. Order by triviality:
N_SLICE → N_TUPLE → N_ALLOC → N_RECV → N_SPREAD → N_YIELD →
N_MATCH → assertion. Each commit holds invariant; cgen readers
migrate in A.6.3.

Verified 132/132 incl. 995_self_rebuild byte-identity.
This commit is contained in:
2026-05-21 20:16:24 +09:00
parent 0e1ab38586
commit c564d7d0fd
3 changed files with 117 additions and 0 deletions

View File

@@ -8769,6 +8769,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
e.type_ = tinfofornode(c, arr): *void;
return arr;
};
if (k == nkind.N_SLICE) {
// A.6.2.0a — head-only stamp of the slice expression's overall
// type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel
// alias on the base; [N]T → []T, []T → []T (return base), str
// → str, *T (non-nil sub) → []T. Slice bounds (e.rhs start,
// e.cond end) are already covered by the post-order dispatch
// at L460-489 (typically N_INTLIT/N_IDENT/N_BIN, all in the
// dispatch list), so we do not double-walk them here.
// Documented cstage divergence: cstage L1227 errors on a
// non-sliceable 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_TARRAY) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
if (bu.kind == nkind.N_TSLICE) {
e.type_ = tinfofornode(c, basetn): *void;
return basetn;
};
if (bu.kind == nkind.N_TNAME) {
if (streq(bu.str, "str")) {
let tn: *node = mktname(c, "str");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
};
if (bu.kind == nkind.N_TPTR && bu.lhs != nil) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
return nil;
};
if (k == nkind.N_TRYPROP) {
// success unwrap: the success-variant type of operand's
// tagged union.

View File

@@ -1837,6 +1837,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
e.type_ = tinfofornode(c, arr): *void;
return arr;
};
if (k == nkind.N_SLICE) {
// A.6.2.0a — head-only stamp of the slice expression's overall
// type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel
// alias on the base; [N]T → []T, []T → []T (return base), str
// → str, *T (non-nil sub) → []T. Slice bounds (e.rhs start,
// e.cond end) are already covered by the post-order dispatch
// at L460-489 (typically N_INTLIT/N_IDENT/N_BIN, all in the
// dispatch list), so we do not double-walk them here.
// Documented cstage divergence: cstage L1227 errors on a
// non-sliceable 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_TARRAY) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
if (bu.kind == nkind.N_TSLICE) {
e.type_ = tinfofornode(c, basetn): *void;
return basetn;
};
if (bu.kind == nkind.N_TNAME) {
if (streq(bu.str, "str")) {
let tn: *node = mktname(c, "str");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
};
if (bu.kind == nkind.N_TPTR && bu.lhs != nil) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
return nil;
};
if (k == nkind.N_TRYPROP) {
// success unwrap: the success-variant type of operand's
// tagged union.

View File

@@ -8769,6 +8769,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
e.type_ = tinfofornode(c, arr): *void;
return arr;
};
if (k == nkind.N_SLICE) {
// A.6.2.0a — head-only stamp of the slice expression's overall
// type. Mirrors cstage cmd/wcc/check.c:1214-1228 N_SLICE: peel
// alias on the base; [N]T → []T, []T → []T (return base), str
// → str, *T (non-nil sub) → []T. Slice bounds (e.rhs start,
// e.cond end) are already covered by the post-order dispatch
// at L460-489 (typically N_INTLIT/N_IDENT/N_BIN, all in the
// dispatch list), so we do not double-walk them here.
// Documented cstage divergence: cstage L1227 errors on a
// non-sliceable 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_TARRAY) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
if (bu.kind == nkind.N_TSLICE) {
e.type_ = tinfofornode(c, basetn): *void;
return basetn;
};
if (bu.kind == nkind.N_TNAME) {
if (streq(bu.str, "str")) {
let tn: *node = mktname(c, "str");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
};
if (bu.kind == nkind.N_TPTR && bu.lhs != nil) {
let sl: *node = newnode(nkind.N_TSLICE, "", 0, 0);
sl.lhs = bu.lhs;
e.type_ = tinfofornode(c, sl): *void;
return sl;
};
return nil;
};
if (k == nkind.N_TRYPROP) {
// success unwrap: the success-variant type of operand's
// tagged union.