commit f2288a8e4b733bf4df17e9da638ca54e4dbb585b (tree)
parent b8d749cc3796400e0aff95f1fd67e047dcdad71b
Author: Motiejus <motiejus@jakstys.lt>
Date: Sun, 1 Mar 2026 16:39:57 +0000
stage0: add anti-pattern rule against filling the IP gap dishonestly
Document that pre-resolving types/declarations by name to fill the IP
gap is forbidden. This applies to builtin types, std types, module
declarations, or any other source. Every IP entry must be a side
effect of honestly porting the upstream function that produces it.
Also format return_integer.zig to canonical form.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/stage0/CLAUDE.md b/stage0/CLAUDE.md
@@ -57,19 +57,20 @@ take shortcuts. Instead, decompose:
### Current status (2026-03-01)
-**num_passing = 4.** The first 4 sema unit tests pass the full bidirectional
-pipeline (empty.zig, const_decl.zig, empty_void_function.zig,
-type_identity_fn.zig). These are standalone files without imports and without
-complex type references.
-
-**Next blocker: reify_int.zig** (index 5). Uses `const U32 = @Type(...)`.
-The C sema produces IP index 35 for u32 instead of the pre-interned index 8.
-Root cause: the module-level IP entry creation via `createFileRootStructC`
-produces different entries than the Zig compiler, shifting all subsequent
-IP indices.
-
-ALL sema tests with functions that reference types (index 5+) fail with
-similar IP reference mismatches (`zig_ip_base` differs between C and Zig).
+**num_passing = 5.** The first 5 sema unit tests pass (empty.zig,
+const_decl.zig, empty_void_function.zig, type_identity_fn.zig,
+reify_int.zig). reify_int.zig was fixed by handling `decl_val` in
+2-instruction parameter type bodies.
+
+**Next blocker: return_integer.zig** (index 6). Uses `return 42` which
+interns a non-pre-interned value (42:u32). The IP index of this value
+depends on the module-level entry count. The Zig compiler (even for
+standalone files with `std_mod=null`) always creates std from `lib_dir`,
+producing `func_ip=217` (215 base + 2 function body entries). The C sema
+creates only ~135 entries. The gap of ~80 entries comes from the @export
+trigger chain: `zirExport` → `resolveExportOptions` → `getBuiltinType`
+→ `analyzeMemoizedState`, which resolves builtin types from
+`std.builtin` as side effects. Port this chain to close the gap.
### Background
@@ -136,6 +137,17 @@ similar IP reference mismatches (`zig_ip_base` differs between C and Zig).
`scanNamespace`, `ensureFileAnalyzed`, etc.) correctly. Port those
functions mechanically from `src/Zcu/PerThread.zig` to C; do not try
to understand every individual IP entry before starting to code.
+- **NEVER fill the IP gap by pre-resolving types or declarations.**
+ Do NOT resolve declarations by name, enumerate namespaces, or force
+ type evaluation just to create IP entries and "fill up" the gap.
+ This applies to builtin types, std types, module declarations, or
+ any other source. Every IP entry must be created as a side effect
+ of honestly porting the upstream function that produces it. If the
+ Zig compiler creates entries through `zirExport` → `getBuiltinType`
+ → `analyzeMemoizedState`, then port that chain. If it creates
+ entries through `scanNamespace` → `analyzeNav`, port that. Do not
+ invent shortcuts that produce the right count but through the wrong
+ mechanism.
- Time-box investigation. Spend at most ~10 minutes investigating a
problem before writing code. Use `--verbose-intern-pool` dumps to
verify progress after each batch, not to plan the entire
diff --git a/stage0/sema_tests/return_integer.zig b/stage0/sema_tests/return_integer.zig
@@ -1 +1,3 @@
-export fn f() u32 { return 42; }
+export fn f() u32 {
+ return 42;
+}