P5.7 Step B2: remove the #compiler attribute + compiler_expr AST node
The #compiler struct attribute + #compiler-suffixed bodyless methods were fully superseded by abi(.compiler) (P5.5) — no sx code uses them. Remove the hash_compiler token (token/lexer/lsp), the is_compiler_struct / struct_default_compiler parser machinery + the two compiler_expr body- synthesis branches, the compiler_expr AST variant, and every .builtin_expr/.compiler_expr switch arm + == .compiler_expr check across sema/resolver/semantic_diagnostics/generic/decl/call/calls (kept .builtin_expr). abi(.compiler) is untouched. Delete the obsolete calls.test.zig dispatch test. 500/500 unit + 706/0 corpus.
This commit is contained in:
@@ -21,11 +21,6 @@ pub const Parser = struct {
|
||||
diagnostics: ?*errors.DiagnosticList = null,
|
||||
/// Type param names from enclosing generic struct (set while parsing methods)
|
||||
struct_type_params: []const []const u8 = &.{},
|
||||
/// When true (set while parsing methods inside `struct #compiler { ... }`),
|
||||
/// a missing function body (just `name :: (params);`) is synthesized as
|
||||
/// a `.compiler_expr` body so the per-method `#compiler` suffix can be
|
||||
/// omitted.
|
||||
struct_default_compiler: bool = false,
|
||||
/// When true (set while parsing a `for` header's iterable expressions),
|
||||
/// a top-level `(` group immediately followed by `{` or `=>` is the loop
|
||||
/// CAPTURE, never call arguments — `for xs (x) { }` reads `(x)` as the
|
||||
@@ -950,15 +945,6 @@ pub const Parser = struct {
|
||||
fn parseStructDecl(self: *Parser, name: []const u8, start_pos: u32, name_is_raw: bool) anyerror!*Node {
|
||||
self.advance(); // skip 'struct'
|
||||
|
||||
// Optional `#compiler` attribute: all methods inside this struct are
|
||||
// implicitly compiler hooks (no per-method `#compiler` suffix needed).
|
||||
// Mirrors `protocol #inline { ... }` shape.
|
||||
var is_compiler_struct = false;
|
||||
if (self.current.tag == .hash_compiler) {
|
||||
is_compiler_struct = true;
|
||||
self.advance();
|
||||
}
|
||||
|
||||
// Optional welded-binding annotation: `struct abi(.zig) extern <lib> { … }`.
|
||||
// `abi(...)` (the ABI/layout selector) sits before the `extern` linkage
|
||||
// keyword, mirroring the fn-decl slot order; the library handle follows.
|
||||
@@ -1023,13 +1009,6 @@ pub const Parser = struct {
|
||||
self.struct_type_params = tp_names.items;
|
||||
defer self.struct_type_params = saved_struct_type_params;
|
||||
|
||||
// Propagate the struct-level `#compiler` flag to nested method
|
||||
// parsing so a bodyless `name :: (params);` synthesizes a
|
||||
// `.compiler_expr` body.
|
||||
const saved_struct_default_compiler = self.struct_default_compiler;
|
||||
self.struct_default_compiler = is_compiler_struct;
|
||||
defer self.struct_default_compiler = saved_struct_default_compiler;
|
||||
|
||||
var field_names = std.ArrayList([]const u8).empty;
|
||||
var field_types = std.ArrayList(*Node).empty;
|
||||
var field_defaults = std.ArrayList(?*Node).empty;
|
||||
@@ -2014,17 +1993,6 @@ pub const Parser = struct {
|
||||
self.advance();
|
||||
try self.expect(.semicolon);
|
||||
break :blk try self.createNode(bi_start, .{ .builtin_expr = {} });
|
||||
} else if (self.current.tag == .hash_compiler) blk: {
|
||||
const ci_start = self.current.loc.start;
|
||||
self.advance();
|
||||
try self.expect(.semicolon);
|
||||
break :blk try self.createNode(ci_start, .{ .compiler_expr = {} });
|
||||
} else if (self.struct_default_compiler and self.current.tag == .semicolon) blk: {
|
||||
// Inside `struct #compiler { ... }`: a bodyless method is
|
||||
// implicitly a `#compiler` hook.
|
||||
const ci_start = self.current.loc.start;
|
||||
self.advance();
|
||||
break :blk try self.createNode(ci_start, .{ .compiler_expr = {} });
|
||||
} else if (self.current.tag == .fat_arrow) blk: {
|
||||
is_arrow = true;
|
||||
self.advance();
|
||||
@@ -3765,16 +3733,12 @@ pub const Parser = struct {
|
||||
|
||||
fn isFunctionDef(self: *Parser) bool {
|
||||
const tag = self.peekPastParens() orelse return false;
|
||||
// Inside `struct #compiler { ... }`, a bodyless method declaration
|
||||
// ends with `;` directly after the param list — recognise it as a
|
||||
// function def (not a constant) so it goes through parseFnDecl.
|
||||
if (self.struct_default_compiler and tag == .semicolon) return true;
|
||||
// `(T1, T2) -> R` without a trailing body (`{`, `=>`, or an extern/
|
||||
// builtin marker) is a function-type literal, not a function def.
|
||||
if (tag == .arrow) return self.hasFnBodyAfterArrow();
|
||||
// `kw_extern`/`kw_export`: a postfix linkage modifier (e.g. `f :: () extern;`
|
||||
// with no return type) marks a fn decl just like `abi(...)`.
|
||||
return tag == .l_brace or tag == .hash_builtin or tag == .hash_compiler or tag == .fat_arrow or tag == .kw_abi or tag == .kw_extern or tag == .kw_export;
|
||||
return tag == .l_brace or tag == .hash_builtin or tag == .fat_arrow or tag == .kw_abi or tag == .kw_extern or tag == .kw_export;
|
||||
}
|
||||
|
||||
fn hasFnBodyAfterArrow(self: *Parser) bool {
|
||||
@@ -3800,17 +3764,11 @@ pub const Parser = struct {
|
||||
while (self.current.tag != .eof) {
|
||||
if (self.current.tag == .fat_arrow) return true;
|
||||
if (self.current.tag == .l_brace) return true;
|
||||
if (self.current.tag == .hash_builtin or self.current.tag == .hash_compiler) return true;
|
||||
if (self.current.tag == .hash_builtin) return true;
|
||||
if (self.current.tag == .kw_abi) return true;
|
||||
// Postfix linkage modifier after the return type: `-> R extern;` /
|
||||
// `-> R export { … }` (and `-> R abi(.c) extern`). Marks a fn def.
|
||||
if (self.current.tag == .kw_extern or self.current.tag == .kw_export) return true;
|
||||
// Inside a `struct #compiler` block, a `(...) -> Ret;` ending
|
||||
// with `;` after the return type is a `#compiler` method
|
||||
// declaration (body implicit). Outside that context, the same
|
||||
// shape is a function-type alias (no body) and falls through to
|
||||
// const-decl parsing.
|
||||
if (self.struct_default_compiler and self.current.tag == .semicolon) return true;
|
||||
if (self.current.tag == .identifier or self.current.tag.isTypeKeyword() or
|
||||
self.current.tag == .dot or self.current.tag == .dollar or
|
||||
self.current.tag == .l_bracket or self.current.tag == .r_bracket or
|
||||
|
||||
Reference in New Issue
Block a user