authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-04-02 12:00:23+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-04-02 12:00:23+01:00
log896ffe66586035e11080d25deeb9dbba477684fe
tree47493a121e8f330438f75c06249ebc80b47b9d12
parent1b62a22268117340ee7a17f019df01cd39ec1421
parentfa1695a8b0f611a67166732a4fb0d0eff2c6db42
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22973 from MasonRemaley/zon-stop-on-node

Allow parsing into `Zoir.Node.Index` (it's easier to parse build.zig.zon at runtime now)

1 files changed, 476 insertions(+), 439 deletions(-)

lib/std/zon/parse.zig+476-439
......@@ -44,14 +44,13 @@ pub const Error = union(enum) {
4444 pub const Iterator = struct {
4545 index: usize = 0,
4646 err: Error,
47 status: *const Status,
47 diag: *const Diagnostics,
4848
4949 pub fn next(self: *@This()) ?Note {
5050 switch (self.err) {
5151 .zoir => |err| {
5252 if (self.index >= err.note_count) return null;
53 const zoir = self.status.zoir.?;
54 const note = err.getNotes(zoir)[self.index];
53 const note = err.getNotes(self.diag.zoir)[self.index];
5554 self.index += 1;
5655 return .{ .zoir = note };
5756 },
......@@ -80,37 +79,34 @@ pub const Error = union(enum) {
8079 try writer.writeAll(self);
8180 }
8281
83 pub fn fmtMessage(self: Note, status: *const Status) std.fmt.Formatter(Note.formatMessage) {
82 pub fn fmtMessage(self: Note, diag: *const Diagnostics) std.fmt.Formatter(Note.formatMessage) {
8483 return .{ .data = switch (self) {
85 .zoir => |note| note.msg.get(status.zoir.?),
84 .zoir => |note| note.msg.get(diag.zoir),
8685 .type_check => |note| note.msg,
8786 } };
8887 }
8988
90 pub fn getLocation(self: Note, status: *const Status) Ast.Location {
91 const ast = status.ast.?;
89 pub fn getLocation(self: Note, diag: *const Diagnostics) Ast.Location {
9290 switch (self) {
93 .zoir => |note| return zoirErrorLocation(ast, note.token, note.node_or_offset),
94 .type_check => |note| return ast.tokenLocation(note.offset, note.token),
91 .zoir => |note| return zoirErrorLocation(diag.ast, note.token, note.node_or_offset),
92 .type_check => |note| return diag.ast.tokenLocation(note.offset, note.token),
9593 }
9694 }
9795 };
9896
9997 pub const Iterator = struct {
10098 index: usize = 0,
101 status: *const Status,
99 diag: *const Diagnostics,
102100
103101 pub fn next(self: *@This()) ?Error {
104 const zoir = self.status.zoir orelse return null;
105
106 if (self.index < zoir.compile_errors.len) {
107 const result: Error = .{ .zoir = zoir.compile_errors[self.index] };
102 if (self.index < self.diag.zoir.compile_errors.len) {
103 const result: Error = .{ .zoir = self.diag.zoir.compile_errors[self.index] };
108104 self.index += 1;
109105 return result;
110106 }
111107
112 if (self.status.type_check) |err| {
113 if (self.index == zoir.compile_errors.len) {
108 if (self.diag.type_check) |err| {
109 if (self.index == self.diag.zoir.compile_errors.len) {
114110 const result: Error = .{ .type_check = err };
115111 self.index += 1;
116112 return result;
......@@ -156,7 +152,7 @@ pub const Error = union(enum) {
156152
157153 const FormatMessage = struct {
158154 err: Error,
159 status: *const Status,
155 diag: *const Diagnostics,
160156 };
161157
162158 fn formatMessage(
......@@ -168,32 +164,31 @@ pub const Error = union(enum) {
168164 _ = f;
169165 _ = options;
170166 switch (self.err) {
171 .zoir => |err| try writer.writeAll(err.msg.get(self.status.zoir.?)),
167 .zoir => |err| try writer.writeAll(err.msg.get(self.diag.zoir)),
172168 .type_check => |tc| try writer.writeAll(tc.message),
173169 }
174170 }
175171
176 pub fn fmtMessage(self: @This(), status: *const Status) std.fmt.Formatter(formatMessage) {
172 pub fn fmtMessage(self: @This(), diag: *const Diagnostics) std.fmt.Formatter(formatMessage) {
177173 return .{ .data = .{
178174 .err = self,
179 .status = status,
175 .diag = diag,
180176 } };
181177 }
182178
183 pub fn getLocation(self: @This(), status: *const Status) Ast.Location {
184 const ast = status.ast.?;
179 pub fn getLocation(self: @This(), diag: *const Diagnostics) Ast.Location {
185180 return switch (self) {
186181 .zoir => |err| return zoirErrorLocation(
187 status.ast.?,
182 diag.ast,
188183 err.token,
189184 err.node_or_offset,
190185 ),
191 .type_check => |err| return ast.tokenLocation(err.offset, err.token),
186 .type_check => |err| return diag.ast.tokenLocation(err.offset, err.token),
192187 };
193188 }
194189
195 pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator {
196 return .{ .err = self, .status = status };
190 pub fn iterateNotes(self: @This(), diag: *const Diagnostics) Note.Iterator {
191 return .{ .err = self, .diag = diag };
197192 }
198193
199194 fn zoirErrorLocation(ast: Ast, maybe_token: Ast.OptionalTokenIndex, node_or_offset: u32) Ast.Location {
......@@ -210,26 +205,40 @@ pub const Error = union(enum) {
210205};
211206
212207/// Information about the success or failure of a parse.
213pub const Status = struct {
214 ast: ?Ast = null,
215 zoir: ?Zoir = null,
208pub const Diagnostics = struct {
209 ast: Ast = .{
210 .source = "",
211 .tokens = .empty,
212 .nodes = .empty,
213 .extra_data = &.{},
214 .mode = .zon,
215 .errors = &.{},
216 },
217 zoir: Zoir = .{
218 .nodes = .empty,
219 .extra = &.{},
220 .limbs = &.{},
221 .string_bytes = &.{},
222 .compile_errors = &.{},
223 .error_notes = &.{},
224 },
216225 type_check: ?Error.TypeCheckFailure = null,
217226
218 fn assertEmpty(self: Status) void {
219 assert(self.ast == null);
220 assert(self.zoir == null);
227 fn assertEmpty(self: Diagnostics) void {
228 assert(self.ast.tokens.len == 0);
229 assert(self.zoir.nodes.len == 0);
221230 assert(self.type_check == null);
222231 }
223232
224 pub fn deinit(self: *Status, gpa: Allocator) void {
225 if (self.ast) |*ast| ast.deinit(gpa);
226 if (self.zoir) |*zoir| zoir.deinit(gpa);
233 pub fn deinit(self: *Diagnostics, gpa: Allocator) void {
234 self.ast.deinit(gpa);
235 self.zoir.deinit(gpa);
227236 if (self.type_check) |tc| tc.deinit(gpa);
228237 self.* = undefined;
229238 }
230239
231 pub fn iterateErrors(self: *const Status) Error.Iterator {
232 return .{ .status = self };
240 pub fn iterateErrors(self: *const Diagnostics) Error.Iterator {
241 return .{ .diag = self };
233242 }
234243
235244 pub fn format(
......@@ -266,7 +275,7 @@ pub const Status = struct {
266275/// invalid or can not be deserialized into type `T`.
267276///
268277/// When the parser returns `error.ParseZon`, it will also store a human readable explanation in
269/// `status` if non null. If status is not null, it must be initialized to `.{}`.
278/// `diag` if non null. If diag is not null, it must be initialized to `.{}`.
270279pub fn fromSlice(
271280 /// The type to deserialize into. May not be or contain any of the following types:
272281 /// * Any comptime-only type, except in a comptime field
......@@ -283,22 +292,22 @@ pub fn fromSlice(
283292 T: type,
284293 gpa: Allocator,
285294 source: [:0]const u8,
286 status: ?*Status,
295 diag: ?*Diagnostics,
287296 options: Options,
288297) error{ OutOfMemory, ParseZon }!T {
289 if (status) |s| s.assertEmpty();
298 if (diag) |s| s.assertEmpty();
290299
291300 var ast = try std.zig.Ast.parse(gpa, source, .zon);
292 defer if (status == null) ast.deinit(gpa);
293 if (status) |s| s.ast = ast;
301 defer if (diag == null) ast.deinit(gpa);
302 if (diag) |s| s.ast = ast;
294303
295 // If there's no status, Zoir exists for the lifetime of this function. If there is a status,
296 // ownership is transferred to status.
304 // If there's no diagnostics, Zoir exists for the lifetime of this function. If there is a
305 // diagnostics, ownership is transferred to diagnostics.
297306 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
298 defer if (status == null) zoir.deinit(gpa);
307 defer if (diag == null) zoir.deinit(gpa);
299308
300 if (status) |s| s.* = .{};
301 return fromZoir(T, gpa, ast, zoir, status, options);
309 if (diag) |s| s.* = .{};
310 return fromZoir(T, gpa, ast, zoir, diag, options);
302311}
303312
304313/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.
......@@ -307,10 +316,10 @@ pub fn fromZoir(
307316 gpa: Allocator,
308317 ast: Ast,
309318 zoir: Zoir,
310 status: ?*Status,
319 diag: ?*Diagnostics,
311320 options: Options,
312321) error{ OutOfMemory, ParseZon }!T {
313 return fromZoirNode(T, gpa, ast, zoir, .root, status, options);
322 return fromZoirNode(T, gpa, ast, zoir, .root, diag, options);
314323}
315324
316325/// Like `fromZoir`, but the parse starts on `node` instead of root.
......@@ -320,12 +329,12 @@ pub fn fromZoirNode(
320329 ast: Ast,
321330 zoir: Zoir,
322331 node: Zoir.Node.Index,
323 status: ?*Status,
332 diag: ?*Diagnostics,
324333 options: Options,
325334) error{ OutOfMemory, ParseZon }!T {
326335 comptime assert(canParseType(T));
327336
328 if (status) |s| {
337 if (diag) |s| {
329338 s.assertEmpty();
330339 s.ast = ast;
331340 s.zoir = zoir;
......@@ -340,7 +349,7 @@ pub fn fromZoirNode(
340349 .ast = ast,
341350 .zoir = zoir,
342351 .options = options,
343 .status = status,
352 .diag = diag,
344353 };
345354
346355 return parser.parseExpr(T, node);
......@@ -421,7 +430,7 @@ const Parser = struct {
421430 gpa: Allocator,
422431 ast: Ast,
423432 zoir: Zoir,
424 status: ?*Status,
433 diag: ?*Diagnostics,
425434 options: Options,
426435
427436 fn parseExpr(self: *@This(), T: type, node: Zoir.Node.Index) error{ ParseZon, OutOfMemory }!T {
......@@ -436,6 +445,10 @@ const Parser = struct {
436445 T: type,
437446 node: Zoir.Node.Index,
438447 ) error{ ParseZon, OutOfMemory, WrongType }!T {
448 if (T == Zoir.Node.Index) {
449 return node;
450 }
451
439452 switch (@typeInfo(T)) {
440453 .optional => |optional| if (node.get(self.zoir) == .null) {
441454 return null;
......@@ -984,7 +997,7 @@ const Parser = struct {
984997 ) error{ OutOfMemory, ParseZon } {
985998 @branchHint(.cold);
986999 comptime assert(args.len > 0);
987 if (self.status) |s| s.type_check = .{
1000 if (self.diag) |s| s.type_check = .{
9881001 .token = token,
9891002 .offset = offset,
9901003 .message = std.fmt.allocPrint(self.gpa, fmt, args) catch |err| {
......@@ -1013,7 +1026,7 @@ const Parser = struct {
10131026 failure: Error.TypeCheckFailure,
10141027 ) error{ParseZon} {
10151028 @branchHint(.cold);
1016 if (self.status) |s| s.type_check = failure;
1029 if (self.diag) |s| s.type_check = failure;
10171030 return error.ParseZon;
10181031 }
10191032
......@@ -1279,13 +1292,13 @@ test "std.zon requiresAllocator" {
12791292
12801293test "std.zon ast errors" {
12811294 const gpa = std.testing.allocator;
1282 var status: Status = .{};
1283 defer status.deinit(gpa);
1295 var diag: Diagnostics = .{};
1296 defer diag.deinit(gpa);
12841297 try std.testing.expectError(
12851298 error.ParseZon,
1286 fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &status, .{}),
1299 fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &diag, .{}),
12871300 );
1288 try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{}", .{status});
1301 try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{}", .{diag});
12891302}
12901303
12911304test "std.zon comments" {
......@@ -1298,17 +1311,17 @@ test "std.zon comments" {
12981311 , null, .{}));
12991312
13001313 {
1301 var status: Status = .{};
1302 defer status.deinit(gpa);
1314 var diag: Diagnostics = .{};
1315 defer diag.deinit(gpa);
13031316 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa,
13041317 \\//! comment
13051318 \\10 // comment
13061319 \\// comment
1307 , &status, .{}));
1320 , &diag, .{}));
13081321 try std.testing.expectFmt(
13091322 "1:1: error: expected expression, found 'a document comment'\n",
13101323 "{}",
1311 .{status},
1324 .{diag},
13121325 );
13131326 }
13141327}
......@@ -1319,16 +1332,16 @@ test "std.zon failure/oom formatting" {
13191332 .fail_index = 0,
13201333 .resize_fail_index = 0,
13211334 });
1322 var status: Status = .{};
1323 defer status.deinit(gpa);
1335 var diag: Diagnostics = .{};
1336 defer diag.deinit(gpa);
13241337 try std.testing.expectError(error.OutOfMemory, fromSlice(
13251338 []const u8,
13261339 failing_allocator.allocator(),
13271340 "\"foo\"",
1328 &status,
1341 &diag,
13291342 .{},
13301343 ));
1331 try std.testing.expectFmt("", "{}", .{status});
1344 try std.testing.expectFmt("", "{}", .{diag});
13321345}
13331346
13341347test "std.zon fromSlice syntax error" {
......@@ -1397,11 +1410,11 @@ test "std.zon unions" {
13971410 // Unknown field
13981411 {
13991412 const Union = union { x: f32, y: f32 };
1400 var status: Status = .{};
1401 defer status.deinit(gpa);
1413 var diag: Diagnostics = .{};
1414 defer diag.deinit(gpa);
14021415 try std.testing.expectError(
14031416 error.ParseZon,
1404 fromSlice(Union, gpa, ".{.z=2.5}", &status, .{}),
1417 fromSlice(Union, gpa, ".{.z=2.5}", &diag, .{}),
14051418 );
14061419 try std.testing.expectFmt(
14071420 \\1:4: error: unexpected field 'z'
......@@ -1409,78 +1422,78 @@ test "std.zon unions" {
14091422 \\
14101423 ,
14111424 "{}",
1412 .{status},
1425 .{diag},
14131426 );
14141427 }
14151428
14161429 // Explicit void field
14171430 {
14181431 const Union = union(enum) { x: void };
1419 var status: Status = .{};
1420 defer status.deinit(gpa);
1432 var diag: Diagnostics = .{};
1433 defer diag.deinit(gpa);
14211434 try std.testing.expectError(
14221435 error.ParseZon,
1423 fromSlice(Union, gpa, ".{.x=1}", &status, .{}),
1436 fromSlice(Union, gpa, ".{.x=1}", &diag, .{}),
14241437 );
1425 try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{}", .{status});
1438 try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{}", .{diag});
14261439 }
14271440
14281441 // Extra field
14291442 {
14301443 const Union = union { x: f32, y: bool };
1431 var status: Status = .{};
1432 defer status.deinit(gpa);
1444 var diag: Diagnostics = .{};
1445 defer diag.deinit(gpa);
14331446 try std.testing.expectError(
14341447 error.ParseZon,
1435 fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &status, .{}),
1448 fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &diag, .{}),
14361449 );
1437 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});
1450 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
14381451 }
14391452
14401453 // No fields
14411454 {
14421455 const Union = union { x: f32, y: bool };
1443 var status: Status = .{};
1444 defer status.deinit(gpa);
1456 var diag: Diagnostics = .{};
1457 defer diag.deinit(gpa);
14451458 try std.testing.expectError(
14461459 error.ParseZon,
1447 fromSlice(Union, gpa, ".{}", &status, .{}),
1460 fromSlice(Union, gpa, ".{}", &diag, .{}),
14481461 );
1449 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});
1462 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
14501463 }
14511464
14521465 // Enum literals cannot coerce into untagged unions
14531466 {
14541467 const Union = union { x: void };
1455 var status: Status = .{};
1456 defer status.deinit(gpa);
1457 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{}));
1458 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});
1468 var diag: Diagnostics = .{};
1469 defer diag.deinit(gpa);
1470 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{}));
1471 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
14591472 }
14601473
14611474 // Unknown field for enum literal coercion
14621475 {
14631476 const Union = union(enum) { x: void };
1464 var status: Status = .{};
1465 defer status.deinit(gpa);
1466 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &status, .{}));
1477 var diag: Diagnostics = .{};
1478 defer diag.deinit(gpa);
1479 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &diag, .{}));
14671480 try std.testing.expectFmt(
14681481 \\1:2: error: unexpected field 'y'
14691482 \\1:2: note: supported: 'x'
14701483 \\
14711484 ,
14721485 "{}",
1473 .{status},
1486 .{diag},
14741487 );
14751488 }
14761489
14771490 // Non void field for enum literal coercion
14781491 {
14791492 const Union = union(enum) { x: f32 };
1480 var status: Status = .{};
1481 defer status.deinit(gpa);
1482 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{}));
1483 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});
1493 var diag: Diagnostics = .{};
1494 defer diag.deinit(gpa);
1495 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{}));
1496 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
14841497 }
14851498}
14861499
......@@ -1525,11 +1538,11 @@ test "std.zon structs" {
15251538 // Unknown field
15261539 {
15271540 const Vec2 = struct { x: f32, y: f32 };
1528 var status: Status = .{};
1529 defer status.deinit(gpa);
1541 var diag: Diagnostics = .{};
1542 defer diag.deinit(gpa);
15301543 try std.testing.expectError(
15311544 error.ParseZon,
1532 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}),
1545 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),
15331546 );
15341547 try std.testing.expectFmt(
15351548 \\1:12: error: unexpected field 'z'
......@@ -1537,24 +1550,24 @@ test "std.zon structs" {
15371550 \\
15381551 ,
15391552 "{}",
1540 .{status},
1553 .{diag},
15411554 );
15421555 }
15431556
15441557 // Duplicate field
15451558 {
15461559 const Vec2 = struct { x: f32, y: f32 };
1547 var status: Status = .{};
1548 defer status.deinit(gpa);
1560 var diag: Diagnostics = .{};
1561 defer diag.deinit(gpa);
15491562 try std.testing.expectError(
15501563 error.ParseZon,
1551 fromSlice(Vec2, gpa, ".{.x=1.5, .x=2.5, .x=3.5}", &status, .{}),
1564 fromSlice(Vec2, gpa, ".{.x=1.5, .x=2.5, .x=3.5}", &diag, .{}),
15521565 );
15531566 try std.testing.expectFmt(
15541567 \\1:4: error: duplicate struct field name
15551568 \\1:12: note: duplicate name here
15561569 \\
1557 , "{}", .{status});
1570 , "{}", .{diag});
15581571 }
15591572
15601573 // Ignore unknown fields
......@@ -1569,29 +1582,29 @@ test "std.zon structs" {
15691582 // Unknown field when struct has no fields (regression test)
15701583 {
15711584 const Vec2 = struct {};
1572 var status: Status = .{};
1573 defer status.deinit(gpa);
1585 var diag: Diagnostics = .{};
1586 defer diag.deinit(gpa);
15741587 try std.testing.expectError(
15751588 error.ParseZon,
1576 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}),
1589 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),
15771590 );
15781591 try std.testing.expectFmt(
15791592 \\1:4: error: unexpected field 'x'
15801593 \\1:4: note: none expected
15811594 \\
1582 , "{}", .{status});
1595 , "{}", .{diag});
15831596 }
15841597
15851598 // Missing field
15861599 {
15871600 const Vec2 = struct { x: f32, y: f32 };
1588 var status: Status = .{};
1589 defer status.deinit(gpa);
1601 var diag: Diagnostics = .{};
1602 defer diag.deinit(gpa);
15901603 try std.testing.expectError(
15911604 error.ParseZon,
1592 fromSlice(Vec2, gpa, ".{.x=1.5}", &status, .{}),
1605 fromSlice(Vec2, gpa, ".{.x=1.5}", &diag, .{}),
15931606 );
1594 try std.testing.expectFmt("1:2: error: missing required field y\n", "{}", .{status});
1607 try std.testing.expectFmt("1:2: error: missing required field y\n", "{}", .{diag});
15951608 }
15961609
15971610 // Default field
......@@ -1611,14 +1624,14 @@ test "std.zon structs" {
16111624 // Comptime field assignment
16121625 {
16131626 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1614 var status: Status = .{};
1615 defer status.deinit(gpa);
1616 const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &status, .{});
1627 var diag: Diagnostics = .{};
1628 defer diag.deinit(gpa);
1629 const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &diag, .{});
16171630 try std.testing.expectError(error.ParseZon, parsed);
16181631 try std.testing.expectFmt(
16191632 \\1:18: error: cannot initialize comptime field
16201633 \\
1621 , "{}", .{status});
1634 , "{}", .{diag});
16221635 }
16231636
16241637 // Enum field (regression test, we were previously getting the field name in an
......@@ -1640,52 +1653,52 @@ test "std.zon structs" {
16401653 {
16411654 // Structs
16421655 {
1643 var status: Status = .{};
1644 defer status.deinit(gpa);
1645 const parsed = fromSlice(struct {}, gpa, "Empty{}", &status, .{});
1656 var diag: Diagnostics = .{};
1657 defer diag.deinit(gpa);
1658 const parsed = fromSlice(struct {}, gpa, "Empty{}", &diag, .{});
16461659 try std.testing.expectError(error.ParseZon, parsed);
16471660 try std.testing.expectFmt(
16481661 \\1:1: error: types are not available in ZON
16491662 \\1:1: note: replace the type with '.'
16501663 \\
1651 , "{}", .{status});
1664 , "{}", .{diag});
16521665 }
16531666
16541667 // Arrays
16551668 {
1656 var status: Status = .{};
1657 defer status.deinit(gpa);
1658 const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &status, .{});
1669 var diag: Diagnostics = .{};
1670 defer diag.deinit(gpa);
1671 const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &diag, .{});
16591672 try std.testing.expectError(error.ParseZon, parsed);
16601673 try std.testing.expectFmt(
16611674 \\1:1: error: types are not available in ZON
16621675 \\1:1: note: replace the type with '.'
16631676 \\
1664 , "{}", .{status});
1677 , "{}", .{diag});
16651678 }
16661679
16671680 // Slices
16681681 {
1669 var status: Status = .{};
1670 defer status.deinit(gpa);
1671 const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &status, .{});
1682 var diag: Diagnostics = .{};
1683 defer diag.deinit(gpa);
1684 const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &diag, .{});
16721685 try std.testing.expectError(error.ParseZon, parsed);
16731686 try std.testing.expectFmt(
16741687 \\1:1: error: types are not available in ZON
16751688 \\1:1: note: replace the type with '.'
16761689 \\
1677 , "{}", .{status});
1690 , "{}", .{diag});
16781691 }
16791692
16801693 // Tuples
16811694 {
1682 var status: Status = .{};
1683 defer status.deinit(gpa);
1695 var diag: Diagnostics = .{};
1696 defer diag.deinit(gpa);
16841697 const parsed = fromSlice(
16851698 struct { u8, u8, u8 },
16861699 gpa,
16871700 "Tuple{1, 2, 3}",
1688 &status,
1701 &diag,
16891702 .{},
16901703 );
16911704 try std.testing.expectError(error.ParseZon, parsed);
......@@ -1693,20 +1706,20 @@ test "std.zon structs" {
16931706 \\1:1: error: types are not available in ZON
16941707 \\1:1: note: replace the type with '.'
16951708 \\
1696 , "{}", .{status});
1709 , "{}", .{diag});
16971710 }
16981711
16991712 // Nested
17001713 {
1701 var status: Status = .{};
1702 defer status.deinit(gpa);
1703 const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &status, .{});
1714 var diag: Diagnostics = .{};
1715 defer diag.deinit(gpa);
1716 const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &diag, .{});
17041717 try std.testing.expectError(error.ParseZon, parsed);
17051718 try std.testing.expectFmt(
17061719 \\1:9: error: types are not available in ZON
17071720 \\1:9: note: replace the type with '.'
17081721 \\
1709 , "{}", .{status});
1722 , "{}", .{diag});
17101723 }
17111724 }
17121725}
......@@ -1745,53 +1758,53 @@ test "std.zon tuples" {
17451758 // Extra field
17461759 {
17471760 const Tuple = struct { f32, bool };
1748 var status: Status = .{};
1749 defer status.deinit(gpa);
1761 var diag: Diagnostics = .{};
1762 defer diag.deinit(gpa);
17501763 try std.testing.expectError(
17511764 error.ParseZon,
1752 fromSlice(Tuple, gpa, ".{0.5, true, 123}", &status, .{}),
1765 fromSlice(Tuple, gpa, ".{0.5, true, 123}", &diag, .{}),
17531766 );
1754 try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{}", .{status});
1767 try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{}", .{diag});
17551768 }
17561769
17571770 // Extra field
17581771 {
17591772 const Tuple = struct { f32, bool };
1760 var status: Status = .{};
1761 defer status.deinit(gpa);
1773 var diag: Diagnostics = .{};
1774 defer diag.deinit(gpa);
17621775 try std.testing.expectError(
17631776 error.ParseZon,
1764 fromSlice(Tuple, gpa, ".{0.5}", &status, .{}),
1777 fromSlice(Tuple, gpa, ".{0.5}", &diag, .{}),
17651778 );
17661779 try std.testing.expectFmt(
17671780 "1:2: error: missing tuple field with index 1\n",
17681781 "{}",
1769 .{status},
1782 .{diag},
17701783 );
17711784 }
17721785
17731786 // Tuple with unexpected field names
17741787 {
17751788 const Tuple = struct { f32 };
1776 var status: Status = .{};
1777 defer status.deinit(gpa);
1789 var diag: Diagnostics = .{};
1790 defer diag.deinit(gpa);
17781791 try std.testing.expectError(
17791792 error.ParseZon,
1780 fromSlice(Tuple, gpa, ".{.foo = 10.0}", &status, .{}),
1793 fromSlice(Tuple, gpa, ".{.foo = 10.0}", &diag, .{}),
17811794 );
1782 try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{status});
1795 try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{diag});
17831796 }
17841797
17851798 // Struct with missing field names
17861799 {
17871800 const Struct = struct { foo: f32 };
1788 var status: Status = .{};
1789 defer status.deinit(gpa);
1801 var diag: Diagnostics = .{};
1802 defer diag.deinit(gpa);
17901803 try std.testing.expectError(
17911804 error.ParseZon,
1792 fromSlice(Struct, gpa, ".{10.0}", &status, .{}),
1805 fromSlice(Struct, gpa, ".{10.0}", &diag, .{}),
17931806 );
1794 try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{status});
1807 try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{diag});
17951808 }
17961809
17971810 // Comptime field
......@@ -1804,14 +1817,14 @@ test "std.zon tuples" {
18041817 // Comptime field assignment
18051818 {
18061819 const Vec2 = struct { f32, comptime f32 = 1.5 };
1807 var status: Status = .{};
1808 defer status.deinit(gpa);
1809 const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &status, .{});
1820 var diag: Diagnostics = .{};
1821 defer diag.deinit(gpa);
1822 const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &diag, .{});
18101823 try std.testing.expectError(error.ParseZon, parsed);
18111824 try std.testing.expectFmt(
18121825 \\1:9: error: cannot initialize comptime field
18131826 \\
1814 , "{}", .{status});
1827 , "{}", .{diag});
18151828 }
18161829}
18171830
......@@ -1915,61 +1928,61 @@ test "std.zon arrays and slices" {
19151928
19161929 // Expect 0 find 3
19171930 {
1918 var status: Status = .{};
1919 defer status.deinit(gpa);
1931 var diag: Diagnostics = .{};
1932 defer diag.deinit(gpa);
19201933 try std.testing.expectError(
19211934 error.ParseZon,
1922 fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &status, .{}),
1935 fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
19231936 );
19241937 try std.testing.expectFmt(
19251938 "1:3: error: index 0 outside of array of length 0\n",
19261939 "{}",
1927 .{status},
1940 .{diag},
19281941 );
19291942 }
19301943
19311944 // Expect 1 find 2
19321945 {
1933 var status: Status = .{};
1934 defer status.deinit(gpa);
1946 var diag: Diagnostics = .{};
1947 defer diag.deinit(gpa);
19351948 try std.testing.expectError(
19361949 error.ParseZon,
1937 fromSlice([1]u8, gpa, ".{'a', 'b'}", &status, .{}),
1950 fromSlice([1]u8, gpa, ".{'a', 'b'}", &diag, .{}),
19381951 );
19391952 try std.testing.expectFmt(
19401953 "1:8: error: index 1 outside of array of length 1\n",
19411954 "{}",
1942 .{status},
1955 .{diag},
19431956 );
19441957 }
19451958
19461959 // Expect 2 find 1
19471960 {
1948 var status: Status = .{};
1949 defer status.deinit(gpa);
1961 var diag: Diagnostics = .{};
1962 defer diag.deinit(gpa);
19501963 try std.testing.expectError(
19511964 error.ParseZon,
1952 fromSlice([2]u8, gpa, ".{'a'}", &status, .{}),
1965 fromSlice([2]u8, gpa, ".{'a'}", &diag, .{}),
19531966 );
19541967 try std.testing.expectFmt(
19551968 "1:2: error: expected 2 array elements; found 1\n",
19561969 "{}",
1957 .{status},
1970 .{diag},
19581971 );
19591972 }
19601973
19611974 // Expect 3 find 0
19621975 {
1963 var status: Status = .{};
1964 defer status.deinit(gpa);
1976 var diag: Diagnostics = .{};
1977 defer diag.deinit(gpa);
19651978 try std.testing.expectError(
19661979 error.ParseZon,
1967 fromSlice([3]u8, gpa, ".{}", &status, .{}),
1980 fromSlice([3]u8, gpa, ".{}", &diag, .{}),
19681981 );
19691982 try std.testing.expectFmt(
19701983 "1:2: error: expected 3 array elements; found 0\n",
19711984 "{}",
1972 .{status},
1985 .{diag},
19731986 );
19741987 }
19751988
......@@ -1977,24 +1990,24 @@ test "std.zon arrays and slices" {
19771990 {
19781991 // Array
19791992 {
1980 var status: Status = .{};
1981 defer status.deinit(gpa);
1993 var diag: Diagnostics = .{};
1994 defer diag.deinit(gpa);
19821995 try std.testing.expectError(
19831996 error.ParseZon,
1984 fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}),
1997 fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
19851998 );
1986 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{status});
1999 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{diag});
19872000 }
19882001
19892002 // Slice
19902003 {
1991 var status: Status = .{};
1992 defer status.deinit(gpa);
2004 var diag: Diagnostics = .{};
2005 defer diag.deinit(gpa);
19932006 try std.testing.expectError(
19942007 error.ParseZon,
1995 fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}),
2008 fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
19962009 );
1997 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{status});
2010 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{}", .{diag});
19982011 }
19992012 }
20002013
......@@ -2002,39 +2015,39 @@ test "std.zon arrays and slices" {
20022015 {
20032016 // Array
20042017 {
2005 var status: Status = .{};
2006 defer status.deinit(gpa);
2018 var diag: Diagnostics = .{};
2019 defer diag.deinit(gpa);
20072020 try std.testing.expectError(
20082021 error.ParseZon,
2009 fromSlice([3]u8, gpa, "'a'", &status, .{}),
2022 fromSlice([3]u8, gpa, "'a'", &diag, .{}),
20102023 );
2011 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2024 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
20122025 }
20132026
20142027 // Slice
20152028 {
2016 var status: Status = .{};
2017 defer status.deinit(gpa);
2029 var diag: Diagnostics = .{};
2030 defer diag.deinit(gpa);
20182031 try std.testing.expectError(
20192032 error.ParseZon,
2020 fromSlice([]u8, gpa, "'a'", &status, .{}),
2033 fromSlice([]u8, gpa, "'a'", &diag, .{}),
20212034 );
2022 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2035 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
20232036 }
20242037 }
20252038
20262039 // Address of is not allowed (indirection for slices in ZON is implicit)
20272040 {
2028 var status: Status = .{};
2029 defer status.deinit(gpa);
2041 var diag: Diagnostics = .{};
2042 defer diag.deinit(gpa);
20302043 try std.testing.expectError(
20312044 error.ParseZon,
2032 fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &status, .{}),
2045 fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &diag, .{}),
20332046 );
20342047 try std.testing.expectFmt(
20352048 "1:3: error: pointers are not available in ZON\n",
20362049 "{}",
2037 .{status},
2050 .{diag},
20382051 );
20392052 }
20402053}
......@@ -2066,23 +2079,23 @@ test "std.zon string literal" {
20662079 // Passing string literal to a mutable slice
20672080 {
20682081 {
2069 var status: Status = .{};
2070 defer status.deinit(gpa);
2082 var diag: Diagnostics = .{};
2083 defer diag.deinit(gpa);
20712084 try std.testing.expectError(
20722085 error.ParseZon,
2073 fromSlice([]u8, gpa, "\"abcd\"", &status, .{}),
2086 fromSlice([]u8, gpa, "\"abcd\"", &diag, .{}),
20742087 );
2075 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2088 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
20762089 }
20772090
20782091 {
2079 var status: Status = .{};
2080 defer status.deinit(gpa);
2092 var diag: Diagnostics = .{};
2093 defer diag.deinit(gpa);
20812094 try std.testing.expectError(
20822095 error.ParseZon,
2083 fromSlice([]u8, gpa, "\\\\abcd", &status, .{}),
2096 fromSlice([]u8, gpa, "\\\\abcd", &diag, .{}),
20842097 );
2085 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2098 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
20862099 }
20872100 }
20882101
......@@ -2093,23 +2106,23 @@ test "std.zon string literal" {
20932106 defer ast.deinit(gpa);
20942107 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
20952108 defer zoir.deinit(gpa);
2096 var status: Status = .{};
2097 defer status.deinit(gpa);
2109 var diag: Diagnostics = .{};
2110 defer diag.deinit(gpa);
20982111 try std.testing.expectError(
20992112 error.ParseZon,
2100 fromSlice([4:0]u8, gpa, "\"abcd\"", &status, .{}),
2113 fromSlice([4:0]u8, gpa, "\"abcd\"", &diag, .{}),
21012114 );
2102 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2115 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
21032116 }
21042117
21052118 {
2106 var status: Status = .{};
2107 defer status.deinit(gpa);
2119 var diag: Diagnostics = .{};
2120 defer diag.deinit(gpa);
21082121 try std.testing.expectError(
21092122 error.ParseZon,
2110 fromSlice([4:0]u8, gpa, "\\\\abcd", &status, .{}),
2123 fromSlice([4:0]u8, gpa, "\\\\abcd", &diag, .{}),
21112124 );
2112 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2125 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
21132126 }
21142127 }
21152128
......@@ -2145,102 +2158,102 @@ test "std.zon string literal" {
21452158 // Other value terminated slices
21462159 {
21472160 {
2148 var status: Status = .{};
2149 defer status.deinit(gpa);
2161 var diag: Diagnostics = .{};
2162 defer diag.deinit(gpa);
21502163 try std.testing.expectError(
21512164 error.ParseZon,
2152 fromSlice([:1]const u8, gpa, "\"foo\"", &status, .{}),
2165 fromSlice([:1]const u8, gpa, "\"foo\"", &diag, .{}),
21532166 );
2154 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2167 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
21552168 }
21562169
21572170 {
2158 var status: Status = .{};
2159 defer status.deinit(gpa);
2171 var diag: Diagnostics = .{};
2172 defer diag.deinit(gpa);
21602173 try std.testing.expectError(
21612174 error.ParseZon,
2162 fromSlice([:1]const u8, gpa, "\\\\foo", &status, .{}),
2175 fromSlice([:1]const u8, gpa, "\\\\foo", &diag, .{}),
21632176 );
2164 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2177 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
21652178 }
21662179 }
21672180
21682181 // Expecting string literal, getting something else
21692182 {
2170 var status: Status = .{};
2171 defer status.deinit(gpa);
2183 var diag: Diagnostics = .{};
2184 defer diag.deinit(gpa);
21722185 try std.testing.expectError(
21732186 error.ParseZon,
2174 fromSlice([]const u8, gpa, "true", &status, .{}),
2187 fromSlice([]const u8, gpa, "true", &diag, .{}),
21752188 );
2176 try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{status});
2189 try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{diag});
21772190 }
21782191
21792192 // Expecting string literal, getting an incompatible tuple
21802193 {
2181 var status: Status = .{};
2182 defer status.deinit(gpa);
2194 var diag: Diagnostics = .{};
2195 defer diag.deinit(gpa);
21832196 try std.testing.expectError(
21842197 error.ParseZon,
2185 fromSlice([]const u8, gpa, ".{false}", &status, .{}),
2198 fromSlice([]const u8, gpa, ".{false}", &diag, .{}),
21862199 );
2187 try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{}", .{status});
2200 try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{}", .{diag});
21882201 }
21892202
21902203 // Invalid string literal
21912204 {
2192 var status: Status = .{};
2193 defer status.deinit(gpa);
2205 var diag: Diagnostics = .{};
2206 defer diag.deinit(gpa);
21942207 try std.testing.expectError(
21952208 error.ParseZon,
2196 fromSlice([]const i8, gpa, "\"\\a\"", &status, .{}),
2209 fromSlice([]const i8, gpa, "\"\\a\"", &diag, .{}),
21972210 );
2198 try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{}", .{status});
2211 try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{}", .{diag});
21992212 }
22002213
22012214 // Slice wrong child type
22022215 {
22032216 {
2204 var status: Status = .{};
2205 defer status.deinit(gpa);
2217 var diag: Diagnostics = .{};
2218 defer diag.deinit(gpa);
22062219 try std.testing.expectError(
22072220 error.ParseZon,
2208 fromSlice([]const i8, gpa, "\"a\"", &status, .{}),
2221 fromSlice([]const i8, gpa, "\"a\"", &diag, .{}),
22092222 );
2210 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2223 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
22112224 }
22122225
22132226 {
2214 var status: Status = .{};
2215 defer status.deinit(gpa);
2227 var diag: Diagnostics = .{};
2228 defer diag.deinit(gpa);
22162229 try std.testing.expectError(
22172230 error.ParseZon,
2218 fromSlice([]const i8, gpa, "\\\\a", &status, .{}),
2231 fromSlice([]const i8, gpa, "\\\\a", &diag, .{}),
22192232 );
2220 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2233 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
22212234 }
22222235 }
22232236
22242237 // Bad alignment
22252238 {
22262239 {
2227 var status: Status = .{};
2228 defer status.deinit(gpa);
2240 var diag: Diagnostics = .{};
2241 defer diag.deinit(gpa);
22292242 try std.testing.expectError(
22302243 error.ParseZon,
2231 fromSlice([]align(2) const u8, gpa, "\"abc\"", &status, .{}),
2244 fromSlice([]align(2) const u8, gpa, "\"abc\"", &diag, .{}),
22322245 );
2233 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2246 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
22342247 }
22352248
22362249 {
2237 var status: Status = .{};
2238 defer status.deinit(gpa);
2250 var diag: Diagnostics = .{};
2251 defer diag.deinit(gpa);
22392252 try std.testing.expectError(
22402253 error.ParseZon,
2241 fromSlice([]align(2) const u8, gpa, "\\\\abc", &status, .{}),
2254 fromSlice([]align(2) const u8, gpa, "\\\\abc", &diag, .{}),
22422255 );
2243 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});
2256 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
22442257 }
22452258 }
22462259
......@@ -2303,11 +2316,11 @@ test "std.zon enum literals" {
23032316
23042317 // Bad tag
23052318 {
2306 var status: Status = .{};
2307 defer status.deinit(gpa);
2319 var diag: Diagnostics = .{};
2320 defer diag.deinit(gpa);
23082321 try std.testing.expectError(
23092322 error.ParseZon,
2310 fromSlice(Enum, gpa, ".qux", &status, .{}),
2323 fromSlice(Enum, gpa, ".qux", &diag, .{}),
23112324 );
23122325 try std.testing.expectFmt(
23132326 \\1:2: error: unexpected enum literal 'qux'
......@@ -2315,17 +2328,17 @@ test "std.zon enum literals" {
23152328 \\
23162329 ,
23172330 "{}",
2318 .{status},
2331 .{diag},
23192332 );
23202333 }
23212334
23222335 // Bad tag that's too long for parser
23232336 {
2324 var status: Status = .{};
2325 defer status.deinit(gpa);
2337 var diag: Diagnostics = .{};
2338 defer diag.deinit(gpa);
23262339 try std.testing.expectError(
23272340 error.ParseZon,
2328 fromSlice(Enum, gpa, ".@\"foobarbaz\"", &status, .{}),
2341 fromSlice(Enum, gpa, ".@\"foobarbaz\"", &diag, .{}),
23292342 );
23302343 try std.testing.expectFmt(
23312344 \\1:2: error: unexpected enum literal 'foobarbaz'
......@@ -2333,33 +2346,33 @@ test "std.zon enum literals" {
23332346 \\
23342347 ,
23352348 "{}",
2336 .{status},
2349 .{diag},
23372350 );
23382351 }
23392352
23402353 // Bad type
23412354 {
2342 var status: Status = .{};
2343 defer status.deinit(gpa);
2355 var diag: Diagnostics = .{};
2356 defer diag.deinit(gpa);
23442357 try std.testing.expectError(
23452358 error.ParseZon,
2346 fromSlice(Enum, gpa, "true", &status, .{}),
2359 fromSlice(Enum, gpa, "true", &diag, .{}),
23472360 );
2348 try std.testing.expectFmt("1:1: error: expected enum literal\n", "{}", .{status});
2361 try std.testing.expectFmt("1:1: error: expected enum literal\n", "{}", .{diag});
23492362 }
23502363
23512364 // Test embedded nulls in an identifier
23522365 {
2353 var status: Status = .{};
2354 defer status.deinit(gpa);
2366 var diag: Diagnostics = .{};
2367 defer diag.deinit(gpa);
23552368 try std.testing.expectError(
23562369 error.ParseZon,
2357 fromSlice(Enum, gpa, ".@\"\\x00\"", &status, .{}),
2370 fromSlice(Enum, gpa, ".@\"\\x00\"", &diag, .{}),
23582371 );
23592372 try std.testing.expectFmt(
23602373 "1:2: error: identifier cannot contain null bytes\n",
23612374 "{}",
2362 .{status},
2375 .{diag},
23632376 );
23642377 }
23652378}
......@@ -2373,24 +2386,24 @@ test "std.zon parse bool" {
23732386
23742387 // Errors
23752388 {
2376 var status: Status = .{};
2377 defer status.deinit(gpa);
2389 var diag: Diagnostics = .{};
2390 defer diag.deinit(gpa);
23782391 try std.testing.expectError(
23792392 error.ParseZon,
2380 fromSlice(bool, gpa, " foo", &status, .{}),
2393 fromSlice(bool, gpa, " foo", &diag, .{}),
23812394 );
23822395 try std.testing.expectFmt(
23832396 \\1:2: error: invalid expression
23842397 \\1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
23852398 \\1:2: note: precede identifier with '.' for an enum literal
23862399 \\
2387 , "{}", .{status});
2400 , "{}", .{diag});
23882401 }
23892402 {
2390 var status: Status = .{};
2391 defer status.deinit(gpa);
2392 try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &status, .{}));
2393 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{status});
2403 var diag: Diagnostics = .{};
2404 defer diag.deinit(gpa);
2405 try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &diag, .{}));
2406 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{diag});
23942407 }
23952408}
23962409
......@@ -2452,35 +2465,35 @@ test "std.zon parse int" {
24522465 try fromSlice(i66, gpa, "-36893488147419103232", null, .{}),
24532466 );
24542467 {
2455 var status: Status = .{};
2456 defer status.deinit(gpa);
2468 var diag: Diagnostics = .{};
2469 defer diag.deinit(gpa);
24572470 try std.testing.expectError(error.ParseZon, fromSlice(
24582471 i66,
24592472 gpa,
24602473 "36893488147419103232",
2461 &status,
2474 &diag,
24622475 .{},
24632476 ));
24642477 try std.testing.expectFmt(
24652478 "1:1: error: type 'i66' cannot represent value\n",
24662479 "{}",
2467 .{status},
2480 .{diag},
24682481 );
24692482 }
24702483 {
2471 var status: Status = .{};
2472 defer status.deinit(gpa);
2484 var diag: Diagnostics = .{};
2485 defer diag.deinit(gpa);
24732486 try std.testing.expectError(error.ParseZon, fromSlice(
24742487 i66,
24752488 gpa,
24762489 "-36893488147419103233",
2477 &status,
2490 &diag,
24782491 .{},
24792492 ));
24802493 try std.testing.expectFmt(
24812494 "1:1: error: type 'i66' cannot represent value\n",
24822495 "{}",
2483 .{status},
2496 .{diag},
24842497 );
24852498 }
24862499
......@@ -2563,108 +2576,108 @@ test "std.zon parse int" {
25632576
25642577 // Number with invalid character in the middle
25652578 {
2566 var status: Status = .{};
2567 defer status.deinit(gpa);
2568 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &status, .{}));
2579 var diag: Diagnostics = .{};
2580 defer diag.deinit(gpa);
2581 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &diag, .{}));
25692582 try std.testing.expectFmt(
25702583 "1:3: error: invalid digit 'a' for decimal base\n",
25712584 "{}",
2572 .{status},
2585 .{diag},
25732586 );
25742587 }
25752588
25762589 // Failing to parse as int
25772590 {
2578 var status: Status = .{};
2579 defer status.deinit(gpa);
2580 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &status, .{}));
2581 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{status});
2591 var diag: Diagnostics = .{};
2592 defer diag.deinit(gpa);
2593 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &diag, .{}));
2594 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{diag});
25822595 }
25832596
25842597 // Failing because an int is out of range
25852598 {
2586 var status: Status = .{};
2587 defer status.deinit(gpa);
2588 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &status, .{}));
2599 var diag: Diagnostics = .{};
2600 defer diag.deinit(gpa);
2601 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &diag, .{}));
25892602 try std.testing.expectFmt(
25902603 "1:1: error: type 'u8' cannot represent value\n",
25912604 "{}",
2592 .{status},
2605 .{diag},
25932606 );
25942607 }
25952608
25962609 // Failing because a negative int is out of range
25972610 {
2598 var status: Status = .{};
2599 defer status.deinit(gpa);
2600 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &status, .{}));
2611 var diag: Diagnostics = .{};
2612 defer diag.deinit(gpa);
2613 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &diag, .{}));
26012614 try std.testing.expectFmt(
26022615 "1:1: error: type 'i8' cannot represent value\n",
26032616 "{}",
2604 .{status},
2617 .{diag},
26052618 );
26062619 }
26072620
26082621 // Failing because an unsigned int is negative
26092622 {
2610 var status: Status = .{};
2611 defer status.deinit(gpa);
2612 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &status, .{}));
2623 var diag: Diagnostics = .{};
2624 defer diag.deinit(gpa);
2625 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &diag, .{}));
26132626 try std.testing.expectFmt(
26142627 "1:1: error: type 'u8' cannot represent value\n",
26152628 "{}",
2616 .{status},
2629 .{diag},
26172630 );
26182631 }
26192632
26202633 // Failing because a float is non-whole
26212634 {
2622 var status: Status = .{};
2623 defer status.deinit(gpa);
2624 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &status, .{}));
2635 var diag: Diagnostics = .{};
2636 defer diag.deinit(gpa);
2637 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &diag, .{}));
26252638 try std.testing.expectFmt(
26262639 "1:1: error: type 'u8' cannot represent value\n",
26272640 "{}",
2628 .{status},
2641 .{diag},
26292642 );
26302643 }
26312644
26322645 // Failing because a float is negative
26332646 {
2634 var status: Status = .{};
2635 defer status.deinit(gpa);
2636 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &status, .{}));
2647 var diag: Diagnostics = .{};
2648 defer diag.deinit(gpa);
2649 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &diag, .{}));
26372650 try std.testing.expectFmt(
26382651 "1:1: error: type 'u8' cannot represent value\n",
26392652 "{}",
2640 .{status},
2653 .{diag},
26412654 );
26422655 }
26432656
26442657 // Negative integer zero
26452658 {
2646 var status: Status = .{};
2647 defer status.deinit(gpa);
2648 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &status, .{}));
2659 var diag: Diagnostics = .{};
2660 defer diag.deinit(gpa);
2661 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &diag, .{}));
26492662 try std.testing.expectFmt(
26502663 \\1:2: error: integer literal '-0' is ambiguous
26512664 \\1:2: note: use '0' for an integer zero
26522665 \\1:2: note: use '-0.0' for a floating-point signed zero
26532666 \\
2654 , "{}", .{status});
2667 , "{}", .{diag});
26552668 }
26562669
26572670 // Negative integer zero casted to float
26582671 {
2659 var status: Status = .{};
2660 defer status.deinit(gpa);
2661 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &status, .{}));
2672 var diag: Diagnostics = .{};
2673 defer diag.deinit(gpa);
2674 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &diag, .{}));
26622675 try std.testing.expectFmt(
26632676 \\1:2: error: integer literal '-0' is ambiguous
26642677 \\1:2: note: use '0' for an integer zero
26652678 \\1:2: note: use '-0.0' for a floating-point signed zero
26662679 \\
2667 , "{}", .{status});
2680 , "{}", .{diag});
26682681 }
26692682
26702683 // Negative float 0 is allowed
......@@ -2675,48 +2688,48 @@ test "std.zon parse int" {
26752688
26762689 // Double negation is not allowed
26772690 {
2678 var status: Status = .{};
2679 defer status.deinit(gpa);
2680 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &status, .{}));
2691 var diag: Diagnostics = .{};
2692 defer diag.deinit(gpa);
2693 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &diag, .{}));
26812694 try std.testing.expectFmt(
26822695 "1:1: error: expected number or 'inf' after '-'\n",
26832696 "{}",
2684 .{status},
2697 .{diag},
26852698 );
26862699 }
26872700
26882701 {
2689 var status: Status = .{};
2690 defer status.deinit(gpa);
2702 var diag: Diagnostics = .{};
2703 defer diag.deinit(gpa);
26912704 try std.testing.expectError(
26922705 error.ParseZon,
2693 fromSlice(f32, gpa, "--2.0", &status, .{}),
2706 fromSlice(f32, gpa, "--2.0", &diag, .{}),
26942707 );
26952708 try std.testing.expectFmt(
26962709 "1:1: error: expected number or 'inf' after '-'\n",
26972710 "{}",
2698 .{status},
2711 .{diag},
26992712 );
27002713 }
27012714
27022715 // Invalid int literal
27032716 {
2704 var status: Status = .{};
2705 defer status.deinit(gpa);
2706 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &status, .{}));
2707 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{status});
2717 var diag: Diagnostics = .{};
2718 defer diag.deinit(gpa);
2719 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &diag, .{}));
2720 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{diag});
27082721 }
27092722
27102723 // Notes on invalid int literal
27112724 {
2712 var status: Status = .{};
2713 defer status.deinit(gpa);
2714 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &status, .{}));
2725 var diag: Diagnostics = .{};
2726 defer diag.deinit(gpa);
2727 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &diag, .{}));
27152728 try std.testing.expectFmt(
27162729 \\1:1: error: number '0123' has leading zero
27172730 \\1:1: note: use '0o' prefix for octal literals
27182731 \\
2719 , "{}", .{status});
2732 , "{}", .{diag});
27202733 }
27212734}
27222735
......@@ -2724,23 +2737,23 @@ test "std.zon negative char" {
27242737 const gpa = std.testing.allocator;
27252738
27262739 {
2727 var status: Status = .{};
2728 defer status.deinit(gpa);
2729 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &status, .{}));
2740 var diag: Diagnostics = .{};
2741 defer diag.deinit(gpa);
2742 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &diag, .{}));
27302743 try std.testing.expectFmt(
27312744 "1:1: error: expected number or 'inf' after '-'\n",
27322745 "{}",
2733 .{status},
2746 .{diag},
27342747 );
27352748 }
27362749 {
2737 var status: Status = .{};
2738 defer status.deinit(gpa);
2739 try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &status, .{}));
2750 var diag: Diagnostics = .{};
2751 defer diag.deinit(gpa);
2752 try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &diag, .{}));
27402753 try std.testing.expectFmt(
27412754 "1:1: error: expected number or 'inf' after '-'\n",
27422755 "{}",
2743 .{status},
2756 .{diag},
27442757 );
27452758 }
27462759}
......@@ -2821,81 +2834,81 @@ test "std.zon parse float" {
28212834
28222835 // Negative nan not allowed
28232836 {
2824 var status: Status = .{};
2825 defer status.deinit(gpa);
2826 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &status, .{}));
2837 var diag: Diagnostics = .{};
2838 defer diag.deinit(gpa);
2839 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &diag, .{}));
28272840 try std.testing.expectFmt(
28282841 "1:1: error: expected number or 'inf' after '-'\n",
28292842 "{}",
2830 .{status},
2843 .{diag},
28312844 );
28322845 }
28332846
28342847 // nan as int not allowed
28352848 {
2836 var status: Status = .{};
2837 defer status.deinit(gpa);
2838 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{}));
2839 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});
2849 var diag: Diagnostics = .{};
2850 defer diag.deinit(gpa);
2851 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));
2852 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
28402853 }
28412854
28422855 // nan as int not allowed
28432856 {
2844 var status: Status = .{};
2845 defer status.deinit(gpa);
2846 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{}));
2847 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});
2857 var diag: Diagnostics = .{};
2858 defer diag.deinit(gpa);
2859 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));
2860 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
28482861 }
28492862
28502863 // inf as int not allowed
28512864 {
2852 var status: Status = .{};
2853 defer status.deinit(gpa);
2854 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &status, .{}));
2855 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});
2865 var diag: Diagnostics = .{};
2866 defer diag.deinit(gpa);
2867 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &diag, .{}));
2868 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
28562869 }
28572870
28582871 // -inf as int not allowed
28592872 {
2860 var status: Status = .{};
2861 defer status.deinit(gpa);
2862 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &status, .{}));
2863 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});
2873 var diag: Diagnostics = .{};
2874 defer diag.deinit(gpa);
2875 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &diag, .{}));
2876 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
28642877 }
28652878
28662879 // Bad identifier as float
28672880 {
2868 var status: Status = .{};
2869 defer status.deinit(gpa);
2870 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &status, .{}));
2881 var diag: Diagnostics = .{};
2882 defer diag.deinit(gpa);
2883 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &diag, .{}));
28712884 try std.testing.expectFmt(
28722885 \\1:1: error: invalid expression
28732886 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
28742887 \\1:1: note: precede identifier with '.' for an enum literal
28752888 \\
2876 , "{}", .{status});
2889 , "{}", .{diag});
28772890 }
28782891
28792892 {
2880 var status: Status = .{};
2881 defer status.deinit(gpa);
2882 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &status, .{}));
2893 var diag: Diagnostics = .{};
2894 defer diag.deinit(gpa);
2895 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &diag, .{}));
28832896 try std.testing.expectFmt(
28842897 "1:1: error: expected number or 'inf' after '-'\n",
28852898 "{}",
2886 .{status},
2899 .{diag},
28872900 );
28882901 }
28892902
28902903 // Non float as float
28912904 {
2892 var status: Status = .{};
2893 defer status.deinit(gpa);
2905 var diag: Diagnostics = .{};
2906 defer diag.deinit(gpa);
28942907 try std.testing.expectError(
28952908 error.ParseZon,
2896 fromSlice(f32, gpa, "\"foo\"", &status, .{}),
2909 fromSlice(f32, gpa, "\"foo\"", &diag, .{}),
28972910 );
2898 try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{}", .{status});
2911 try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{}", .{diag});
28992912 }
29002913}
29012914
......@@ -3132,69 +3145,69 @@ test "std.zon vector" {
31323145
31333146 // Too few fields
31343147 {
3135 var status: Status = .{};
3136 defer status.deinit(gpa);
3148 var diag: Diagnostics = .{};
3149 defer diag.deinit(gpa);
31373150 try std.testing.expectError(
31383151 error.ParseZon,
3139 fromSlice(@Vector(2, f32), gpa, ".{0.5}", &status, .{}),
3152 fromSlice(@Vector(2, f32), gpa, ".{0.5}", &diag, .{}),
31403153 );
31413154 try std.testing.expectFmt(
31423155 "1:2: error: expected 2 vector elements; found 1\n",
31433156 "{}",
3144 .{status},
3157 .{diag},
31453158 );
31463159 }
31473160
31483161 // Too many fields
31493162 {
3150 var status: Status = .{};
3151 defer status.deinit(gpa);
3163 var diag: Diagnostics = .{};
3164 defer diag.deinit(gpa);
31523165 try std.testing.expectError(
31533166 error.ParseZon,
3154 fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &status, .{}),
3167 fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &diag, .{}),
31553168 );
31563169 try std.testing.expectFmt(
31573170 "1:2: error: expected 2 vector elements; found 3\n",
31583171 "{}",
3159 .{status},
3172 .{diag},
31603173 );
31613174 }
31623175
31633176 // Wrong type fields
31643177 {
3165 var status: Status = .{};
3166 defer status.deinit(gpa);
3178 var diag: Diagnostics = .{};
3179 defer diag.deinit(gpa);
31673180 try std.testing.expectError(
31683181 error.ParseZon,
3169 fromSlice(@Vector(3, f32), gpa, ".{0.5, true, 2.5}", &status, .{}),
3182 fromSlice(@Vector(3, f32), gpa, ".{0.5, true, 2.5}", &diag, .{}),
31703183 );
31713184 try std.testing.expectFmt(
31723185 "1:8: error: expected type 'f32'\n",
31733186 "{}",
3174 .{status},
3187 .{diag},
31753188 );
31763189 }
31773190
31783191 // Wrong type
31793192 {
3180 var status: Status = .{};
3181 defer status.deinit(gpa);
3193 var diag: Diagnostics = .{};
3194 defer diag.deinit(gpa);
31823195 try std.testing.expectError(
31833196 error.ParseZon,
3184 fromSlice(@Vector(3, u8), gpa, "true", &status, .{}),
3197 fromSlice(@Vector(3, u8), gpa, "true", &diag, .{}),
31853198 );
3186 try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{}", .{status});
3199 try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{}", .{diag});
31873200 }
31883201
31893202 // Elements should get freed on error
31903203 {
3191 var status: Status = .{};
3192 defer status.deinit(gpa);
3204 var diag: Diagnostics = .{};
3205 defer diag.deinit(gpa);
31933206 try std.testing.expectError(
31943207 error.ParseZon,
3195 fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &status, .{}),
3208 fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &diag, .{}),
31963209 );
3197 try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{}", .{status});
3210 try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{}", .{diag});
31983211 }
31993212}
32003213
......@@ -3312,132 +3325,156 @@ test "std.zon add pointers" {
33123325
33133326 // Test that optional types are flattened correctly in errors
33143327 {
3315 var status: Status = .{};
3316 defer status.deinit(gpa);
3328 var diag: Diagnostics = .{};
3329 defer diag.deinit(gpa);
33173330 try std.testing.expectError(
33183331 error.ParseZon,
3319 fromSlice(*const ?*const u8, gpa, "true", &status, .{}),
3332 fromSlice(*const ?*const u8, gpa, "true", &diag, .{}),
33203333 );
3321 try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{}", .{status});
3334 try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{}", .{diag});
33223335 }
33233336
33243337 {
3325 var status: Status = .{};
3326 defer status.deinit(gpa);
3338 var diag: Diagnostics = .{};
3339 defer diag.deinit(gpa);
33273340 try std.testing.expectError(
33283341 error.ParseZon,
3329 fromSlice(*const ?*const f32, gpa, "true", &status, .{}),
3342 fromSlice(*const ?*const f32, gpa, "true", &diag, .{}),
33303343 );
3331 try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{}", .{status});
3344 try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{}", .{diag});
33323345 }
33333346
33343347 {
3335 var status: Status = .{};
3336 defer status.deinit(gpa);
3348 var diag: Diagnostics = .{};
3349 defer diag.deinit(gpa);
33373350 try std.testing.expectError(
33383351 error.ParseZon,
3339 fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &status, .{}),
3352 fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &diag, .{}),
33403353 );
3341 try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{}", .{status});
3354 try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{}", .{diag});
33423355 }
33433356
33443357 {
3345 var status: Status = .{};
3346 defer status.deinit(gpa);
3358 var diag: Diagnostics = .{};
3359 defer diag.deinit(gpa);
33473360 try std.testing.expectError(
33483361 error.ParseZon,
3349 fromSlice(*const ?*const bool, gpa, "10", &status, .{}),
3362 fromSlice(*const ?*const bool, gpa, "10", &diag, .{}),
33503363 );
3351 try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{}", .{status});
3364 try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{}", .{diag});
33523365 }
33533366
33543367 {
3355 var status: Status = .{};
3356 defer status.deinit(gpa);
3368 var diag: Diagnostics = .{};
3369 defer diag.deinit(gpa);
33573370 try std.testing.expectError(
33583371 error.ParseZon,
3359 fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &status, .{}),
3372 fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &diag, .{}),
33603373 );
3361 try std.testing.expectFmt("1:1: error: expected optional struct\n", "{}", .{status});
3374 try std.testing.expectFmt("1:1: error: expected optional struct\n", "{}", .{diag});
33623375 }
33633376
33643377 {
3365 var status: Status = .{};
3366 defer status.deinit(gpa);
3378 var diag: Diagnostics = .{};
3379 defer diag.deinit(gpa);
33673380 try std.testing.expectError(
33683381 error.ParseZon,
3369 fromSlice(*const ?*const struct { i32 }, gpa, "true", &status, .{}),
3382 fromSlice(*const ?*const struct { i32 }, gpa, "true", &diag, .{}),
33703383 );
3371 try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{}", .{status});
3384 try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{}", .{diag});
33723385 }
33733386
33743387 {
3375 var status: Status = .{};
3376 defer status.deinit(gpa);
3388 var diag: Diagnostics = .{};
3389 defer diag.deinit(gpa);
33773390 try std.testing.expectError(
33783391 error.ParseZon,
3379 fromSlice(*const ?*const union { x: void }, gpa, "true", &status, .{}),
3392 fromSlice(*const ?*const union { x: void }, gpa, "true", &diag, .{}),
33803393 );
3381 try std.testing.expectFmt("1:1: error: expected optional union\n", "{}", .{status});
3394 try std.testing.expectFmt("1:1: error: expected optional union\n", "{}", .{diag});
33823395 }
33833396
33843397 {
3385 var status: Status = .{};
3386 defer status.deinit(gpa);
3398 var diag: Diagnostics = .{};
3399 defer diag.deinit(gpa);
33873400 try std.testing.expectError(
33883401 error.ParseZon,
3389 fromSlice(*const ?*const [3]u8, gpa, "true", &status, .{}),
3402 fromSlice(*const ?*const [3]u8, gpa, "true", &diag, .{}),
33903403 );
3391 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status});
3404 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag});
33923405 }
33933406
33943407 {
3395 var status: Status = .{};
3396 defer status.deinit(gpa);
3408 var diag: Diagnostics = .{};
3409 defer diag.deinit(gpa);
33973410 try std.testing.expectError(
33983411 error.ParseZon,
3399 fromSlice(?[3]u8, gpa, "true", &status, .{}),
3412 fromSlice(?[3]u8, gpa, "true", &diag, .{}),
34003413 );
3401 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status});
3414 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag});
34023415 }
34033416
34043417 {
3405 var status: Status = .{};
3406 defer status.deinit(gpa);
3418 var diag: Diagnostics = .{};
3419 defer diag.deinit(gpa);
34073420 try std.testing.expectError(
34083421 error.ParseZon,
3409 fromSlice(*const ?*const []u8, gpa, "true", &status, .{}),
3422 fromSlice(*const ?*const []u8, gpa, "true", &diag, .{}),
34103423 );
3411 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status});
3424 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag});
34123425 }
34133426
34143427 {
3415 var status: Status = .{};
3416 defer status.deinit(gpa);
3428 var diag: Diagnostics = .{};
3429 defer diag.deinit(gpa);
34173430 try std.testing.expectError(
34183431 error.ParseZon,
3419 fromSlice(?[]u8, gpa, "true", &status, .{}),
3432 fromSlice(?[]u8, gpa, "true", &diag, .{}),
34203433 );
3421 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{status});
3434 try std.testing.expectFmt("1:1: error: expected optional array\n", "{}", .{diag});
34223435 }
34233436
34243437 {
3425 var status: Status = .{};
3426 defer status.deinit(gpa);
3438 var diag: Diagnostics = .{};
3439 defer diag.deinit(gpa);
34273440 try std.testing.expectError(
34283441 error.ParseZon,
3429 fromSlice(*const ?*const []const u8, gpa, "true", &status, .{}),
3442 fromSlice(*const ?*const []const u8, gpa, "true", &diag, .{}),
34303443 );
3431 try std.testing.expectFmt("1:1: error: expected optional string\n", "{}", .{status});
3444 try std.testing.expectFmt("1:1: error: expected optional string\n", "{}", .{diag});
34323445 }
34333446
34343447 {
3435 var status: Status = .{};
3436 defer status.deinit(gpa);
3448 var diag: Diagnostics = .{};
3449 defer diag.deinit(gpa);
34373450 try std.testing.expectError(
34383451 error.ParseZon,
3439 fromSlice(*const ?*const enum { foo }, gpa, "true", &status, .{}),
3452 fromSlice(*const ?*const enum { foo }, gpa, "true", &diag, .{}),
34403453 );
3441 try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{}", .{status});
3454 try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{}", .{diag});
3455 }
3456}
3457
3458test "std.zon stop on node" {
3459 const gpa = std.testing.allocator;
3460
3461 {
3462 const Vec2 = struct {
3463 x: Zoir.Node.Index,
3464 y: f32,
3465 };
3466
3467 var diag: Diagnostics = .{};
3468 defer diag.deinit(gpa);
3469 const result = try fromSlice(Vec2, gpa, ".{ .x = 1.5, .y = 2.5 }", &diag, .{});
3470 try std.testing.expectEqual(result.y, 2.5);
3471 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.5 }, result.x.get(diag.zoir));
3472 }
3473
3474 {
3475 var diag: Diagnostics = .{};
3476 defer diag.deinit(gpa);
3477 const result = try fromSlice(Zoir.Node.Index, gpa, "1.23", &diag, .{});
3478 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.23 }, result.get(diag.zoir));
34423479 }
34433480}