Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
Sweep all src/**.zig comments that cite resolved issues (issue NNNN /
fix-NNNN / KB-N): the invariant or mechanism each comment states is
kept; the historical citation is dropped, per the no-conclusion-comments
rule. Pure-history parentheticals are removed outright. References to
the 16 still-open issues (0030, 0041-0056) are untouched, as are test
NAMES carrying regression provenance (matching the sanctioned
"Regression (issue NNNN)" example-header convention).
Also removes the issues/0019-import-non-transitive-c-scope/ fixture dir
— the issue is superseded and its behavior is covered by
examples/0706-modules-import-non-transitive.sx (the .md writeup stays).
issues/0030's repro .sx stays: that issue is an open feature request.
Gate: zig build OK; zig build test 426/426; run_examples 541/0; zero
expected/ snapshot churn.
Make same-name top-level types in different sources DISTINCT nominal types
instead of collapsing last-wins in the type table (issue 0105).
Registration:
- internNamedTypeDecl assigns a per-decl nominal_id and populates
type_decl_tids. The first author of a name keeps nominal_id 0 (byte-identical
to pre-E2); a genuine cross-module shadow (>=2 distinct normalized-path
authors per the import facts) gets a fresh id -> a distinct TypeId.
- mergeFlat/addOwnDecl stop first-wins-dropping per-source decls (named types +
non-fn const_decls) so every same-name author reaches registration; functions
and var_decls (incl. #foreign extern globals) keep first-wins.
Resolution (selectNominalLeaf):
- own-author wins; else flatTypeAuthorCount over the transitive flat closure:
>=2 distinct -> .ambiguous (loud diagnostic + poison); exactly one -> resolved;
a flat author not yet findByName-registered -> .undeclared stub (not a leak).
- struct-literal type names route through the same source-aware leaf.
- lazyLowerFunction pins the function's own source before resolving its return
type, so a shadowed signature type resolves in its module, not the caller's.
Codegen:
- mangleTypeName appends __n<id> for nonzero nominal_id so same-name shadows get
distinct monomorph symbols (struct_to_string__Box vs __Box__n1).
Library hygiene:
- rename trace.sx's compiler-contracted Frame -> TraceFrame (+ the two compiler
findByName sites) so it never collides with a UI/geometry Frame; the layout is
structural (getFrameStructType / SxFrame), name-independent.
Examples: 0752-0756 pin the five 0105 cases (distinct fields / same fields /
own-wins / ambiguous / alias per-source); 0170 pins the folded anon-struct-field
regression.
Generic substitution and monomorphization-key construction now live in one
module, src/ir/generics.zig, behind a *Lowering facade (GenericResolver),
mirroring CallResolver / ExprTyper. Moved verbatim:
- mangleTypeName + mangleParamList (the mono-key fragment builder),
- mangleGenericName (generic mono key), appendComptimeValueMangle (comptime-value
fragment),
- buildTypeBindings (call-site type-param inference), inferGenericReturnType
(generic return resolution).
inferGenericReturnType now uses a scoped TypeBindingScope (enter/exit with defer)
instead of a manual type_bindings save/restore — the PLAN-ARCH A4.1 "scoped
substitution env" shape; a generics.test.zig assertion confirms the prior
bindings are restored (the issue-0048/0050 leak class, for this field).
Lowering keeps a thin pub mangleTypeName wrapper delegating to
genericResolver().mangleTypeName, because ~30 cross-cutting callers (impl-map
keys, conversion keys, shape keys) reach it well beyond generics. mangleParamList
(sole caller was mangleTypeName) moved fully. The other 4 originals are deleted
(no fallback); their 6 call sites now go through self.genericResolver()
(calls.zig via self.l.genericResolver()).
matchTypeParam / extractTypeParam / isTypeParamDecl widened to pub (the moved
substitution logic calls them); genericResolver() accessor added. The 2
mangleTypeName / inferGenericReturnType unit tests moved from lower.test.zig to
generics.test.zig (driving GenericResolver directly) and wired into the barrel.
monomorphizeFunction / monomorphizePackFn intentionally stay in lower.zig (they
save/restore three fields across nested mono and call emission helpers) — a
heavier scoped-env adoption deferred to an optional sub-step 3.
zig build, zig build test, and tests/run_examples.sh (357/0) all green — no .ir
snapshot churn, confirming the move preserved mono-key/substitution output.