wcc: populate str.sub = u8 -- Phase 2 F1 foundation (both stages)

str IS []u8 (#1 landed the 24B layout); F1 populates the element type
so the step-3 checker collapse can read str.sub instead of special-
casing TY_STR. No reader consumes str.sub yet, so this is byte-id-
neutral: every shared ->sub reader a TY_STR value can reach is
invariant under NULL->u8 -- u8 is unsigned + size-1, matching the
prior NULL-defaults (size->1, signed->0, isstr/istagged->false); the
only ->size derefs are guarded behind esz>1, which stays false for
str.

Verified inert: compiling a fixed source with the pre- and post-F1
compilers emits byte-identical asm on both stages; cross-stage
byte-id holds and full make test (135 tests incl. 990-997) is green.

cstage cmd/wcc/type.c, wwstage lib/ww/typ.ww; combined.ww regenerated
via the canonical make path.
This commit is contained in:
2026-05-24 09:34:54 +09:00
parent 4db680690a
commit fb4c567e0d
4 changed files with 4 additions and 0 deletions

View File

@@ -64,6 +64,7 @@ typesinit(Arena *a)
* Size sourced from the slice SSoT (type_slice) so str and []u8 can
* never drift; no second hardcoded 24. */
ty_str = prim(a, TY_STR, "str", type_slice(a, ty_u8)->size, 8);
ty_str->sub = ty_u8; /* str IS []u8: element is u8 (Phase 2 F1) */
ty_err = prim(a, TY_ERR, "<err>", 0, 1);
ty_never = prim(a, TY_NEVER, "never", 0, 1);
/* #29: predeclared `type nomem = !void;`. NAMED so variant_match

View File

@@ -219,6 +219,7 @@ export fn typesinit(c: *tctx) void = {
// cgdot mirror); retained here as a local until that lands.
let u8slice: *tinfo = typeslice(c.tyu8);
c.tystr = prim(tykind.TY_STR, "str", u8slice.size, 8u64);
c.tystr.sub = c.tyu8; // str IS []u8: element is u8 (Phase 2 F1)
c.tyerr = prim(tykind.TY_ERR, "<err>", 0u64, 1u64);
c.tynever = prim(tykind.TY_NEVER, "never", 0u64, 1u64);

View File

@@ -6549,6 +6549,7 @@ export fn typesinit(c: *tctx) void = {
// cgdot mirror); retained here as a local until that lands.
let u8slice: *tinfo = typeslice(c.tyu8);
c.tystr = prim(tykind.TY_STR, "str", u8slice.size, 8u64);
c.tystr.sub = c.tyu8; // str IS []u8: element is u8 (Phase 2 F1)
c.tyerr = prim(tykind.TY_ERR, "<err>", 0u64, 1u64);
c.tynever = prim(tykind.TY_NEVER, "never", 0u64, 1u64);

View File

@@ -6549,6 +6549,7 @@ export fn typesinit(c: *tctx) void = {
// cgdot mirror); retained here as a local until that lands.
let u8slice: *tinfo = typeslice(c.tyu8);
c.tystr = prim(tykind.TY_STR, "str", u8slice.size, 8u64);
c.tystr.sub = c.tyu8; // str IS []u8: element is u8 (Phase 2 F1)
c.tyerr = prim(tykind.TY_ERR, "<err>", 0u64, 1u64);
c.tynever = prim(tykind.TY_NEVER, "never", 0u64, 1u64);