docs(ffi-linkage): checkpoint — PHASE 8 COMPLETE (cutover); Decision 6 ratified (purge everything); Phase 9 next
This commit is contained in:
@@ -5,7 +5,26 @@ 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 7.4 — migrate straggler examples `#foreign`→`extern`** (`refactor` commit
|
||||
**Phase 8 — CUTOVER: parser hard-rejects `#foreign`** (`feat!` commit `3811311`,
|
||||
preceded by the 8.0 xfail `8180faf` + 3 pre-cutover `refactor`s `2cce6a3`/`720556b`/
|
||||
`d132aab`). **PHASE 8 COMPLETE.** The prefix `#foreign` linkage directive is removed:
|
||||
all four parse sites (const-with-type 316, data global 425, fn body 2065, runtime-class
|
||||
prefix via caller 260) reject it with the migration message *"`#foreign` has been
|
||||
removed; use the postfix `extern` (import) / `export` (define) linkage keyword
|
||||
instead"*; added a span-aware `failAt` for the runtime-class case (the lookahead
|
||||
consumes the token before the reject decision). New example **1176**
|
||||
(`diagnostics-foreign-removed`) pins it. **Pre-cutover migrations** (all green,
|
||||
behavior-preserving): the 7 identity `ffi-foreign-*` test DECLS (`2cce6a3`), the two
|
||||
keyword-neutral diagnostic tests 1172 + 1228 with intentional snapshot regens
|
||||
(`720556b`), and the 4 multi-file example companions Phase 7 missed (0729/a+b, 1617/c,
|
||||
1623/mod — `d132aab`). **Deleted** obsolete tests 1174 (`#foreign`+postfix conflict, now
|
||||
unreachable) + 1620 (`#foreign nosuchunit`, superseded by extern twin 1231), the GATE
|
||||
A→B unit test + `lowerSrcToIr` helper (nothing left to compare), and converted the
|
||||
in-source `parse void function with foreign body` parser test to postfix `extern`.
|
||||
specs.md + readme.md document `extern`/`export` as the sole C-linkage surface. Suite
|
||||
green (646 corpus / 444 unit, 0 failed).
|
||||
|
||||
### Prior: Phase 7.4 — migrate straggler examples `#foreign`→`extern` (`refactor` commit
|
||||
`1a8991a`). **PHASE 7 MIGRATABLE WORK COMPLETE (7.1–7.4 done).** Migrated 16 fn/global
|
||||
examples across categories (0415/0602/0603/1024/1025/1605/1607-1609/1611/1616/1619/
|
||||
1622/1628/1635/1636). Marker'd ones corpus-validated; the 3 unmarked uikit importers
|
||||
@@ -238,34 +257,44 @@ 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 8 (cutover: hard-reject the `#foreign` keyword).** Phases 5–7 COMPLETE:
|
||||
the entire `library/` tree + all incidentally-`#foreign` examples are on `extern`/`export`;
|
||||
only the 24-file keep-list (see Last completed step) still spells `#foreign`, by design.
|
||||
**PART B — Phase 9 (total `foreign` purge — the zero-`foreign` invariant).** Phases 5–8
|
||||
COMPLETE: `extern`/`export` is the sole C-linkage SURFACE; `#foreign` is hard-rejected.
|
||||
**Decision 6 RATIFIED (user, 2026-06-15): PURGE EVERYTHING** — the Phase 9.4 gate is
|
||||
absolute (`grep -rniE 'foreign' src/ library/ examples/ issues/ specs.md readme.md
|
||||
CLAUDE.md` → 0), including `issues/*.md` writeups.
|
||||
|
||||
- **Phase 8.0** (`xfail`): add `examples/11xx-diagnostics-foreign-removed.sx` expecting a
|
||||
clean "`#foreign` removed; use `extern`/`export`" diagnostic — RED while `#foreign` is
|
||||
still accepted.
|
||||
- **Phase 8.1** (`green`): parser hard-rejects `#foreign` (mirror the variadic `name: ..T`
|
||||
cutover). **This is the breaking moment for the 24-file keep-list** — every kept file
|
||||
must be dealt with IN this phase (or a 7.5 pre-step right before it):
|
||||
- Identity feature tests (1205/1207/1218/1219/1306/1318) → migrate their decls to
|
||||
`extern`/`export` (the `.ir`/output stays identical per the A→B gate; may also
|
||||
`git mv` to drop the now-stale `ffi-foreign-*` name + reseed `expected/`). Dedup vs the
|
||||
existing extern twins (1224/1225/1229/1230/1231) — delete if fully redundant.
|
||||
- `foreign`-asserting diagnostics (1172/1174/1219/1228/1620) → these tested `#foreign`
|
||||
behavior; convert to assert the NEW rejection diagnostic, or retarget to `extern`
|
||||
equivalents, regenerating snapshots intentionally (this is the one place regen is
|
||||
correct — it's a deliberate behavior change, not a silent diff).
|
||||
- Comment-only / provenance prose (0716/0729/1216/1223-1231/1332/1348/1349/1426 +
|
||||
issues/0030) → migrate the comment text to `extern` for live-tree files (Phase 9.3
|
||||
needs zero `foreign` in `examples/`); `issues/*.md` prose governed by Decision 6.
|
||||
- `specs.md` drops `#foreign`, documents `extern`/`export` only.
|
||||
- Then **Phase 9** (total `foreign` purge — internal identifiers + docs; needs Decision 5
|
||||
[done] + Decision 6).
|
||||
- **Decision 6 (STILL OPEN)** governs the `issues/*.md` + comment-prose carve-out — the
|
||||
recommended default (keep provenance, gate only the live tree) has been applied through
|
||||
Phase 7; **ratify it with the user before Phase 8.1/9** since it decides how much of the
|
||||
keep-list + issues prose must change.
|
||||
Remaining `foreign` footprint (run `grep -rniIE 'foreign'` per area to scope each step):
|
||||
- **Comment-only `#foreign` in `examples/`** — the deferred provenance comments (0716,
|
||||
0729, 1216, 1223/1224/1225/1229/1230/1231, 1332, 1348, 1349, 1426 + the migrated
|
||||
feature tests' leftover comments + issues/0030.sx). ⚠ Many CONTRAST `#foreign` vs
|
||||
`extern` ("no `#foreign`, no `#library`") — a blind `s/#foreign/extern/` yields
|
||||
nonsense; rewrite each comment to stay coherent. Mechanical-ish but needs reading.
|
||||
- **`issues/*.md` prose** (~12 files) — bug writeups referencing `#foreign`. Rewrite to
|
||||
`extern`/`export` per Decision 6 (purge everything). Provenance is preserved in the
|
||||
git history + the `(Regression issue NNNN)` note, not the keyword spelling.
|
||||
- **Internal `src/` identifiers** (Phase 9.1/9.2 — the big mechanical rename):
|
||||
- 9.1 linkage: `foreign_expr`(still BUILT by `c_import.zig` auto-synthesis — migrate
|
||||
that path first, then the node folds away) · `is_foreign`→`is_extern` · `foreign_lib`/
|
||||
`foreign_name`→`extern_*` · `foreign_name_map`→`extern_name_map` · `callForeign`→
|
||||
`callExtern` · `marshalForeignArg` · `is_foreign_c_api` · `dedupeForeignSymbol` · the
|
||||
"foreign symbol already bound" diagnostic text → "extern symbol" (surfaces in 1172).
|
||||
- 9.2 runtime-class → `Runtime*Class*` (Decision 5 ratified): `ForeignClassDecl`(65) ·
|
||||
`ForeignMethodDecl` · `ForeignClassMember` · `ForeignFieldDecl` · `foreign_class_map` ·
|
||||
`current_foreign_class`/`_method` · `foreign_path` · `parse/tryParseForeignClass*` ·
|
||||
`lowerForeign{Method,Static}Call` · `findForeign*InChain` · `resolveForeign*` ·
|
||||
`register*ForeignClass*` · `*ForeignRefs` · `ForeignRuntime`.
|
||||
- 9.0 surface: the `hash_foreign` token + lexer entry + the 4 parse-path REJECTION
|
||||
stubs + the `lex hash_foreign` test. ⚠ DESIGN CHOICE: keep the token so `#foreign`
|
||||
keeps its nice migration message, or delete it (→ generic "unknown directive")?
|
||||
Recommend KEEP the token + rejection through at least one release for a good
|
||||
deprecation, deferring the token deletion. Decide before 9.0.
|
||||
- 9.3 docs: `CLAUDE.md` still references `#foreign` in several places (file-roles,
|
||||
bundling, the rejected-patterns examples) — purge those too for the gate.
|
||||
- **9.4 acceptance gate:** the absolute grep → 0 across all gated areas.
|
||||
|
||||
Suggested order: 9.3-examples (comment rewrite) + issues/*.md first (low-risk text), then
|
||||
9.1/9.2 internal renames (mechanical, snapshot-neutral — but 9.1's diagnostic-text rename
|
||||
intentionally regens 1172), then 9.0 surface decision, then the 9.4 gate.
|
||||
- **6.2 verification note (carry forward):** the `platform/` runtime modules
|
||||
(uikit/android/android_jni) are NOT compiled by any marker'd host corpus test — verify
|
||||
future platform-adjacent migrations via direct `sx ir` on importers (1610/1606 compile
|
||||
@@ -374,9 +403,11 @@ general `isNameVisible` gate already denied it; only the diagnostic wording dive
|
||||
Part A ratified (bare / postfix / `⇒ callconv(.c)` / lib-separate). Part B:
|
||||
- **Decision 5 RATIFIED** (user, 2026-06-14): runtime-class rename target = `Runtime*Class*`
|
||||
(object-model axis, not linkage). Drives the Phase 9.2 identifier renames.
|
||||
- **Decision 6 STILL OPEN**: historical carve-out — keep `issues/*.md` (+ design-doc prose)
|
||||
as provenance & gate only the live tree (recommended) vs purge everything. The user did
|
||||
NOT confirm this at the Part A milestone; confirm before Phase 9.
|
||||
- **Decision 6 RATIFIED** (user, 2026-06-15): **PURGE EVERYTHING** — the Phase 9.4 gate is
|
||||
absolute, including `issues/*.md` writeups (NOT the recommended keep-provenance default).
|
||||
Every `#foreign`/`foreign` reference in the gated tree (`src/ library/ examples/ issues/
|
||||
specs.md readme.md CLAUDE.md`) is rewritten to `extern`/`export`; provenance lives in git
|
||||
history + `(Regression issue NNNN)` notes, not the keyword spelling.
|
||||
- **Decision 7 RATIFIED** (user, 2026-06-15): **accept the churn** — `#foreign`-spelled
|
||||
decls produce `extern`-worded diagnostics; example 1620 regenerated (only snapshot moved).
|
||||
Aligns with Part B's extern-only end state; the interim oddity is cosmetic and removed at
|
||||
@@ -392,6 +423,21 @@ Part A ratified (bare / postfix / `⇒ callconv(.c)` / lib-separate). Part B:
|
||||
deleted at cutover). Affects only diagnostic wording — IR/behavior identical either way.
|
||||
|
||||
## Log
|
||||
- (8.1 cutover) **PHASE 8 COMPLETE.** Parser hard-rejects `#foreign` at all 4 sites
|
||||
(const/global/fn-body via `self.fail`; runtime-class via `self.failAt` at the caller,
|
||||
new helper); greens xfail 1176. Deleted obsolete 1174 + 1620, the GATE A→B test +
|
||||
`lowerSrcToIr` helper; converted the in-source parser test to postfix `extern`;
|
||||
`extern_export` → `const`. specs.md + readme.md drop `#foreign`. Suite green
|
||||
(646/444). `feat!` `3811311`.
|
||||
- (8.0 xfail) Added `1176-diagnostics-foreign-removed.sx` pinning the desired rejection.
|
||||
RED (still accepted). `test`/xfail `8180faf`.
|
||||
- (8 pre-cutover) Migrated the 4 multi-file example companions Phase 7 missed
|
||||
(0729/a+b, 1617/c, 1623/mod). `refactor` `d132aab`.
|
||||
- (8 pre-cutover) Migrated keyword-neutral diagnostics 1172 (decl→extern, message stays
|
||||
internal "foreign symbol") + 1228 (→ two foreign-free extern symbols c_abs_one/_two),
|
||||
intentional snapshot regens reviewed. `refactor` `720556b`.
|
||||
- (8 pre-cutover) Migrated the 7 identity `ffi-foreign-*` test decls to extern/export
|
||||
(decls only; comments left for Phase 9.3). `refactor` `2cce6a3`.
|
||||
- (7.4 stragglers) **PHASE 7 MIGRATABLE WORK COMPLETE.** Migrated 16 fn/global examples
|
||||
(0415/0602/0603/1024/1025/1605/1607-1609/1611/1616/1619/1622/1628/1635/1636) `#foreign`→
|
||||
`extern`; 1607/1608/1616 (unmarked) verified by `sx ir` probes. 24-file keep-list remains
|
||||
|
||||
Reference in New Issue
Block a user