docs(ffi-linkage): checkpoint — Phase 5.0 global path routed (Part B started)
This commit is contained in:
@@ -5,7 +5,17 @@ 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 4** (green) — **PHASE 4 COMPLETE → PART A DONE; GATE A→B LOCKED.** Four pieces:
|
||||
**Phase 5.0 (global path)** (`refactor` lock, commit `e5ddfbe`) — **PART B STARTED.**
|
||||
First of the four `#foreign` parser paths migrated onto the extern AST: the
|
||||
data-global form `name : T #foreign [lib] ["csym"];` now builds the same
|
||||
extern-named `VarDecl` (`is_extern`/`extern_lib`/`extern_name`) that postfix
|
||||
`extern` already produces, instead of `is_foreign`/`foreign_lib`/`foreign_name`.
|
||||
Behavior-preserving — lowering coalesces both forms identically
|
||||
(`decl.zig:1119,1127,1141`), so zero snapshot churn. Suite green (10/10 steps,
|
||||
444/444 unit, 643 corpus, 0 failed). The fn-decl, const-with-type, and
|
||||
runtime-class `#foreign` paths still build the legacy AST.
|
||||
|
||||
### Prior: Phase 4 (green) — **PHASE 4 COMPLETE → PART A DONE; GATE A→B LOCKED.** Four pieces:
|
||||
(1) **GATE A→B unit test** (`lower.test.zig`, `lowerSrcToIr` helper + "GATE A→B" test) —
|
||||
asserts `#foreign` and `extern`/`export` lower to byte-identical printed IR for a sample
|
||||
fn, data global, and Obj-C runtime class. This is the hard gate: Part B may not start
|
||||
@@ -72,13 +82,28 @@ 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 (`#foreign` becomes an alias for `extern`).** Part A is complete and
|
||||
the A→B gate is locked, so migration can begin. Phase 5.0 (`lock`): route the four
|
||||
`#foreign` parser paths (`parser.zig:316,425,1305,1970`) to build the **same** extern-named
|
||||
AST as `extern`/`export` — suite green, all snapshots unchanged. Phase 5.1 (`lock`): unit
|
||||
test that `#foreign` and `extern` produce identical IR (the gate already covers this — extend
|
||||
or reuse `lowerSrcToIr`). Then Phases 6–7 migrate stdlib + examples (empty snapshot diff per
|
||||
batch), Phase 8 cutover (hard-reject `#foreign`), Phase 9 total `foreign` purge.
|
||||
**PART B — Phase 5.0, remaining three `#foreign` parser paths.** The global path
|
||||
(`parser.zig:425`) is done (commit `e5ddfbe`). Remaining:
|
||||
- **const-with-type** (`parser.zig:316`, `name :: type_expr #foreign …`) — builds a
|
||||
`const_decl` whose value is a `foreign_expr` node. Lowest-risk of the three; route
|
||||
to the extern-named shape used by the fn path. Confirm the value-node lowering path
|
||||
coalesces with extern before committing.
|
||||
- **fn-decl body marker** (`parser.zig:2059`) — **needs prerequisites first**: (a) the
|
||||
deferred **visibility-gate** alignment (`decl.zig:2254` — a lib-less `extern` must be
|
||||
policed like a lib-less `#foreign`; currently bare `extern` is unconditionally visible),
|
||||
which needs a **cross-module example** to lock; (b) **variadic** handling — the
|
||||
`is_variadic` drop at `decl.zig:2097` is gated on `is_foreign` only, so a migrated
|
||||
variadic `#foreign` (e.g. `printf`) would lose its `...` tail unless extended to
|
||||
`is_extern_decl`. Do these (xfail/lock) BEFORE routing the fn path.
|
||||
- **runtime-class prefix** (`parser.zig:1305`, `#foreign #objc_class/#jni_class`) — route
|
||||
the prefix to the same `is_foreign_eff` the postfix `extern` already feeds
|
||||
(`parseForeignClassDecl`); the class node keeps its `is_foreign` field (renamed to a
|
||||
`runtime*` axis only in Phase 9.2, not `extern`).
|
||||
|
||||
Then Phase 5.1 (`lock`): unit test that `#foreign` and `extern` produce identical IR (the
|
||||
A→B gate already covers fn/global/class — extend or reuse `lowerSrcToIr`). Then Phases 6–7
|
||||
migrate stdlib + examples (empty snapshot diff per batch), Phase 8 cutover (hard-reject
|
||||
`#foreign`), Phase 9 total `foreign` purge.
|
||||
|
||||
**⚠ CONFIRM BEFORE PART B (Open decisions 5 & 6):** runtime-class rename target
|
||||
(`Runtime*Class*` recommended vs `Extern*Class*`) and the historical carve-out (keep
|
||||
@@ -119,6 +144,13 @@ Part A ratified (bare / postfix / `⇒ callconv(.c)` / lib-separate). Part B:
|
||||
NOT confirm this at the Part A milestone; confirm before Phase 9.
|
||||
|
||||
## Log
|
||||
- (5.0 global) **PART B STARTED.** Routed the `#foreign` data-global parser path
|
||||
(`parser.zig:425`) onto the extern-named `VarDecl` (`is_extern`/`extern_lib`/
|
||||
`extern_name`) — the same AST postfix `extern` builds. Behavior-preserving
|
||||
(lowering coalesces both at `decl.zig:1119,1127,1141`); zero snapshot churn. Suite
|
||||
green (444/444 unit, 643 corpus). `refactor` lock, commit `e5ddfbe`. Remaining
|
||||
Phase 5.0 paths: const-with-type (316), fn-body (2059, needs visibility+variadic
|
||||
prereqs), runtime-class prefix (1305).
|
||||
- (init) Plan written; FFI-linkage stream opened.
|
||||
- (merge) Folded FOREIGN-MIGRATION in as Part B; deleted the split plan + checkpoint.
|
||||
- (0.0) Added `kw_extern`/`kw_export` tokens + keyword-map entries + LSP keyword
|
||||
|
||||
Reference in New Issue
Block a user