From 346d4a81c330d0fe1ac4ebc6a18d315ccb12582c Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 15 Jun 2026 04:22:24 +0300 Subject: [PATCH] =?UTF-8?q?docs(ffi-linkage):=20checkpoint=20=E2=80=94=20P?= =?UTF-8?q?hase=205.1=20done;=20PHASE=205=20COMPLETE,=20next=20Phase=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- current/CHECKPOINT-EXTERN-EXPORT.md | 41 ++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/current/CHECKPOINT-EXTERN-EXPORT.md b/current/CHECKPOINT-EXTERN-EXPORT.md index 99cd652..80af144 100644 --- a/current/CHECKPOINT-EXTERN-EXPORT.md +++ b/current/CHECKPOINT-EXTERN-EXPORT.md @@ -5,7 +5,20 @@ Companion to `current/PLAN-EXTERN-EXPORT.md` — one merged plan: **Part A** add every commit, one step at a time per the cadence rule. ## Last completed step -**Phase 5.0 — fn-decl `#foreign` body-marker FLIP** (`refactor` commit `6b94bb6`). +**Phase 5.1 — annotate A→B gate post-flip + add fn-rename case** (`test` commit +`93e7b6f`). **PHASE 5 COMPLETE → PART B Phase 5 done.** The A→B gate +(`lower.test.zig`) already asserted `#foreign` ≡ `extern`/`export` byte-identical IR +for fn / global / Obj-C class; post-Phase-5.0 the fn-decl + data-global paths build +the SAME extern-named AST, so cases 1/2 are now STRUCTURALLY identical (guaranteed by +construction, not coincidence). Annotated the gate header to record this and keep it +as a regression tripwire (catches a future reader re-diverging the spellings, or a +revert of the flip); case 3 (runtime class) stays behaviorally — not structurally — +equal via the single `is_foreign_eff` field. Added a fn-rename case (case 2b, +`extern_name` axis: `c_abs` → `"abs"`) to broaden coverage beyond bare import +(verified IR-identical via `sx ir` probe before adding). Test-only, no snapshot churn. +Suite green (647 corpus / 444 unit, 0 failed). + +### Prior: Phase 5.0 — fn-decl `#foreign` body-marker FLIP (`refactor` commit `6b94bb6`). **PHASE 5.0 PARSER ROUTING COMPLETE.** The fn-body `#foreign [LIB] ["csym"]` marker now builds the SAME extern AST postfix `extern` produces (`extern_export = .extern_` + `extern_lib`/`extern_name` + empty-block body) instead of a `foreign_expr` body. @@ -147,15 +160,19 @@ AOT), 1227 (export fn rename, AOT), 1348 (objc extern class), 1349 (objc export (jni extern class), 1174/1175 (interplay diagnostics). ## Next step -**PART B — Phase 5.1: lock `#foreign` ≡ `extern` IR, then Phases 6–7 (migrate -stdlib + examples).** Phase 5.0 parser routing is COMPLETE. +**PART B — Phase 6 (migrate stdlib `#foreign`→`extern`, empty snapshot diff per +batch).** Phase 5 (parser routing 5.0 + gate lock 5.1) is COMPLETE. -- **Phase 5.1** (`lock`/`test`): the A→B gate (`lower.test.zig`) already asserts - `#foreign` ≡ `extern`/`export` byte-identical IR for fn / global / Obj-C class, and - it's now TRIVIALLY true for the fn path (both build the same AST). Decide whether 5.1 - needs anything beyond the existing gate — likely just confirm/annotate it covers the - post-flip world (the fn path no longer has two distinct shapes to compare). Could fold - into a doc note rather than a new test. +- **Phase 6** (`refactor` batches, one commit per batch, snapshot diff must be EMPTY): + rewrite `library/` `#foreign`→`extern` (fns/globals), `#foreign #objc_class`→ + `#objc_class … extern`, defined classes → `… export`. Pure SOURCE rename — the AST is + already unified, so IR/output must be byte-identical per batch. A non-empty diff ⇒ a + reader still branches on `foreign_expr` structurally → STOP and coalesce it first + (don't regen). Batches (from PLAN-EXTERN-EXPORT Phase 6): 6.1 `library/vendors/sqlite/` + (~98 sites), 6.2 `library/modules/platform/` (uikit/android/android_jni/sdl3, ~95), + 6.3 `library/modules/std/` (socket/thread/fs/time/process, ~60), 6.4 + `library/modules/ffi/` (objc/raylib/objc_block, ~50), 6.5 remaining `library/`+ + `vendors/`. Then **Phase 7** migrates examples + issues the same way. - **Phases 6–7** (`refactor` batches, empty snapshot diff per batch): migrate the stdlib + examples from `#foreign` spelling to `extern`. Because the AST is already unified, this is a pure SOURCE rename (`… #foreign LIB "sym";` → `… extern LIB "sym";` @@ -278,6 +295,12 @@ Part A ratified (bare / postfix / `⇒ callconv(.c)` / lib-separate). Part B: deleted at cutover). Affects only diagnostic wording — IR/behavior identical either way. ## Log +- (5.1 gate annotate) **PHASE 5 COMPLETE.** Annotated the A→B gate header + (`lower.test.zig`) to record that post-Phase-5.0 the fn/global `#foreign` paths + build the same extern-named AST → cases 1/2 are structurally (not coincidentally) + identical; the gate stays as a regression tripwire. Added fn-rename case 2b + (`c_abs` → `"abs"`, `extern_name` axis), IR-identical per a `sx ir` probe. + Test-only, no snapshot churn. Suite green (647/444). `test` `93e7b6f`. - (5.0 fn-body flip) **PHASE 5.0 PARSER ROUTING COMPLETE.** Flipped the fn-body `#foreign` parser arm (`parser.zig:~2062`) onto the extern AST (empty-block body + `extern_export = .extern_` + extern_lib/extern_name); `extern_export` made `var` so