ERR/E0.1: error-set decls + ! / !Named type exprs (parser)

Parser-only first step of the error-handling stream. No sema/codegen.

- token: `kw_error` keyword (`!` reuses existing `.bang`).
- ast: `ErrorSetDecl { name, tag_names }` + `ErrorTypeExpr { name: ?[] }`
  (null = inferred `!`, non-null = `!Named`); wired into Node.Data and
  declName.
- parser: `parseErrorSetDecl` (comma-separated tags, optional trailing
  comma/`;`) dispatched from parseConstBinding; `!` / `!Named` parsed in
  parseTypeExpr; result-list loop enforces error type as trailing-only;
  hasFnBodyAfterArrow skips `.bang` so failable-return fns are recognised.
- print: new focused AST round-trip printer (decls + type exprs); loud
  `error.UnsupportedNode` otherwise. Registered in root.zig.
- sema/lsp: exhaustive switch arms for the two new nodes.
- tests: 11 inline parser unit tests (shapes + 3 round-trip prints + 2
  trailing-position rejections).

zig build, zig build test, and 254/254 examples green.
This commit is contained in:
agra
2026-05-31 16:40:22 +03:00
parent f7f9def0e7
commit e88ee66953
7 changed files with 300 additions and 1 deletions

View File

@@ -1155,6 +1155,11 @@ pub const Analyzer = struct {
.union_decl => |ud| {
try self.addSymbol(ud.name, .enum_type, .{ .union_type = ud.name }, node.span);
},
.error_set_decl => |esd| {
// Register the set name; error-set semantics arrive in the ERR
// stream's E1 sema steps.
try self.addSymbol(esd.name, .type_alias, null, node.span);
},
// Leaf nodes — nothing to recurse into
.int_literal,
.float_literal,
@@ -1179,6 +1184,7 @@ pub const Analyzer = struct {
.pointer_type_expr,
.many_pointer_type_expr,
.optional_type_expr,
.error_type_expr,
.pack_index_type_expr,
.comptime_pack_ref,
.null_literal,
@@ -1619,6 +1625,8 @@ pub fn findNodeAtOffset(node: *Node, offset: u32) ?*Node {
.function_type_expr,
.enum_decl,
.union_decl,
.error_set_decl,
.error_type_expr,
.import_decl,
.c_import_decl,
.array_type_expr,