docs: rule len and cap as an i32 stability carve-out

This commit is contained in:
2026-08-09 04:40:40 +09:00
parent ac8ddee6c1
commit 7ab080fe2a
3 changed files with 3 additions and 3 deletions

View File

@@ -6,7 +6,7 @@
6. ref/hare and ref/plan9front are read-only references — consult before inventing data shapes or syntax. Carve-out: the ww compiler frontend is ONE package `lib/ww/syntax/` (tok+lex+ast+sym+typ+parse), a deliberate Go-over-Hare departure modelled on Go's `cmd/compile/internal/syntax` rather than ref/hare/hare's `{ast,lex,parse}` split. Rationale: the split's only payoff is third-party reuse (an IDE wanting `ast` without the parser), which ww has zero of — its frontend is consumed by exactly one client, the `wcc` backend. Consolidating dissolves the cross-package export sprawl (a fn over an unexported sibling type re-triggers sep-build's check_exported_type). Rule 6/12 still bind the internal data shapes (AST kinds, token model, lexer/parser state mirror ref/hare/hare); only the module DECOMPOSITION collapses. The surviving export surface is `syntax`'s public API consumed by `wcc` (a small Hare-faithful set). Ref: USER-approved #74; spec .ai/rob-frontend-reorg.md (rob, drew2 fidelity-confirmed).
7. No workarounds. If a bug forces a workaround, STOP and report with a precise repro. Document any retained divergence at the site with a pointer to the filed task. Never silent.
8. Comments are WHY-only. Never narrate WHAT the code does — names carry the WHAT. Comment only non-obvious WHY: a constraint, a divergence from a reference, a citation to a filed task.
9. Hare-fidelity over convenience. No ad-hoc extensions, renames, or convenience wrappers in lib/. Cite ref/hare/<module>/<file> for every signature ported. Carve-out: the Hare `_unsafe` suffix convention is dropped wholesale (ww is C/Plan-9-lineage, an unmanaged systems language — no GC, no "safe" baseline to be unsafe relative to). bytes→str is a pure reinterpret (`strings.frombytes`, renamed from Hare's `fromutf8_unsafe`); validation is opt-in via `utf8.validate(b)?` at the IO source, never wrapped per-construction. Rationale: ref/hare/strings/utf8.ha:10,22 — the suffix flags Hare's managed-bytes-safety axis, which ww doesn't have. The honest name (`frombytes`) reserves `fromutf8` for a future true validating helper. Carve-out: lib/ tests use Go's external-test-package idiom (`package <mod>_test;` + `import <mod>;`), a sanctioned Go-over-Hare departure — ww hard-rejects self-import (full Go), and Hare's same-package `@test` colocation now has a ww analogue: in-package white-box `@test` files (`package <mod>;`, colocated) are sanctioned alongside the external black-box `package <mod>_test;` split — Go's `foo`/`foo_test` model — now that the non-T `@test` drop landed (#6, harec check.c:3941, 08a76cf; #5 closed). Rule 5/9 binds lib/ *API* surface, not test-authoring style. Ref: Go `foo_test` convention; task #16.
9. Hare-fidelity over convenience. No ad-hoc extensions, renames, or convenience wrappers in lib/. Cite ref/hare/<module>/<file> for every signature ported. Carve-out: the Hare `_unsafe` suffix convention is dropped wholesale (ww is C/Plan-9-lineage, an unmanaged systems language — no GC, no "safe" baseline to be unsafe relative to). bytes→str is a pure reinterpret (`strings.frombytes`, renamed from Hare's `fromutf8_unsafe`); validation is opt-in via `utf8.validate(b)?` at the IO source, never wrapped per-construction. Rationale: ref/hare/strings/utf8.ha:10,22 — the suffix flags Hare's managed-bytes-safety axis, which ww doesn't have. The honest name (`frombytes`) reserves `fromutf8` for a future true validating helper. Carve-out: lib/ tests use Go's external-test-package idiom (`package <mod>_test;` + `import <mod>;`), a sanctioned Go-over-Hare departure — ww hard-rejects self-import (full Go), and Hare's same-package `@test` colocation now has a ww analogue: in-package white-box `@test` files (`package <mod>;`, colocated) are sanctioned alongside the external black-box `package <mod>_test;` split — Go's `foo`/`foo_test` model — now that the non-T `@test` drop landed (#6, harec check.c:3941, 08a76cf; #5 closed). Rule 5/9 binds lib/ *API* surface, not test-authoring style. Ref: Go `foo_test` convention; task #16. Carve-out: `.len`, `.cap`, and `len(x)` remain `i32`, although slice/str header words are 8 bytes and Go returns `int`. This is a deliberate stability exception: ww numeric types do not implicitly interoperate, and the 2026-08-09 strict migration probe found at least 970 new mismatches across 189 paths (575 sites in 57 production lib/internal/selfhost paths). Representation remains word-sized; the checker types `&slice.len`, `&slice.cap`, `&str.len`, and `&str.cap` as `*i64` so indirect writes cover the full header word. Revisit only as a dedicated, independently pinned language migration.
10. Symmetric stages. cstage and wwstage MUST emit byte-identical asm for the same input. When inference power differs, align the richer side DOWN to the leaner side, not the other way.
11. Split commits when they bundle unrelated concerns. Bisect-cleanliness is the default. Multi-fix commits need a body paragraph explaining why they couldn't split.
12. Simple data, simple algorithms. Sea-of-stars style. Mirror Hare's structural choices over clever alternatives.

View File

@@ -12,7 +12,7 @@ Signatures mirror Hare too, modulo:
- Tagged-union returns are spelled with the ww `!` error tag where
Hare uses `!void` / `!T`, and indices use the underlying length
type (`i32` today, since `str.len: i32`). Example:
type (`i32` under root CLAUDE.md rule 9). Example:
`strconv.stoi64(s: str, b: strconv.base) (i64 | invalid | overflow)`
— same shape as Hare's. The base parameter is the named enum
`strconv.base` (Hare uses `enum uint`; we pick `enum i32` to

View File

@@ -39,7 +39,7 @@ type texp = struct {
start_bytesize: size,
matched: bool,
failed: bool,
// .len reads as i32 (check.c:1239), so the count columns match it
// Root CLAUDE.md rule 9 keeps .len at i32, so these counts use i32.
ncaps: i32,
nreps: i32,
};