From e5ddfbe09a771c69ec3f28848f0a8185dd6e5a85 Mon Sep 17 00:00:00 2001 From: agra Date: Sun, 14 Jun 2026 20:31:50 +0300 Subject: [PATCH] =?UTF-8?q?refactor(ffi-linkage):=20Phase=205.0=20?= =?UTF-8?q?=E2=80=94=20route=20#foreign=20global=20decl=20onto=20extern=20?= =?UTF-8?q?AST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part B begins: `#foreign` becomes an alias for `extern`. First of the four `#foreign` parser paths to migrate — the data-global form (`name : T #foreign [lib] ["csym"];`). It now builds the SAME extern-named VarDecl (`is_extern`/`extern_lib`/`extern_name`) that the postfix `extern` global path already produces, instead of `is_foreign`/`foreign_lib`/`foreign_name`. Behavior-preserving: lowering coalesces the two forms identically — the symbol name is `extern_name orelse foreign_name orelse name` (decl.zig:1119), and both `is_foreign` and `is_extern` feed the same `.is_extern` IR flag + early-return (decl.zig:1127,1141). The A->B gate already proved fn/global/class lower to byte-identical IR, so the corpus locks this with 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; they migrate next (the fn path needs the deferred visibility-gate + variadic alignment first). --- src/parser.zig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/parser.zig b/src/parser.zig index 305d078..52b66bd 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -424,6 +424,10 @@ pub const Parser = struct { if (self.current.tag == .hash_foreign) { // name : type #foreign [lib] ["c_name"]; (extern global from libsystem etc.) + // Phase 5.0: `#foreign` is an alias for `extern`. Build the SAME + // extern-named AST the postfix `extern` global path builds below — + // lowering coalesces is_foreign/is_extern identically (decl.zig:1127, + // 1141), so this is behavior-preserving (snapshots unchanged). self.advance(); var lib_ref: ?[]const u8 = null; if (self.current.tag == .identifier) { @@ -442,9 +446,9 @@ pub const Parser = struct { .name_span = name_span, .type_annotation = type_node, .value = null, - .is_foreign = true, - .foreign_lib = lib_ref, - .foreign_name = c_name, + .is_extern = true, + .extern_lib = lib_ref, + .extern_name = c_name, .is_raw = name_is_raw, } }); }