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:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user