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) {...@@ -44,14 +44,13 @@ pub const Error = union(enum) {
44 pub const Iterator = struct {44 pub const Iterator = struct {
45 index: usize = 0,45 index: usize = 0,
46 err: Error,46 err: Error,
47 status: *const Status,47 diag: *const Diagnostics,
4848
49 pub fn next(self: *@This()) ?Note {49 pub fn next(self: *@This()) ?Note {
50 switch (self.err) {50 switch (self.err) {
51 .zoir => |err| {51 .zoir => |err| {
52 if (self.index >= err.note_count) return null;52 if (self.index >= err.note_count) return null;
53 const zoir = self.status.zoir.?;53 const note = err.getNotes(self.diag.zoir)[self.index];
54 const note = err.getNotes(zoir)[self.index];
55 self.index += 1;54 self.index += 1;
56 return .{ .zoir = note };55 return .{ .zoir = note };
57 },56 },
...@@ -80,37 +79,34 @@ pub const Error = union(enum) {...@@ -80,37 +79,34 @@ pub const Error = union(enum) {
80 try writer.writeAll(self);79 try writer.writeAll(self);
81 }80 }
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) {
84 return .{ .data = switch (self) {83 return .{ .data = switch (self) {
85 .zoir => |note| note.msg.get(status.zoir.?),84 .zoir => |note| note.msg.get(diag.zoir),
86 .type_check => |note| note.msg,85 .type_check => |note| note.msg,
87 } };86 } };
88 }87 }
8988
90 pub fn getLocation(self: Note, status: *const Status) Ast.Location {89 pub fn getLocation(self: Note, diag: *const Diagnostics) Ast.Location {
91 const ast = status.ast.?;
92 switch (self) {90 switch (self) {
93 .zoir => |note| return zoirErrorLocation(ast, note.token, note.node_or_offset),91 .zoir => |note| return zoirErrorLocation(diag.ast, note.token, note.node_or_offset),
94 .type_check => |note| return ast.tokenLocation(note.offset, note.token),92 .type_check => |note| return diag.ast.tokenLocation(note.offset, note.token),
95 }93 }
96 }94 }
97 };95 };
9896
99 pub const Iterator = struct {97 pub const Iterator = struct {
100 index: usize = 0,98 index: usize = 0,
101 status: *const Status,99 diag: *const Diagnostics,
102100
103 pub fn next(self: *@This()) ?Error {101 pub fn next(self: *@This()) ?Error {
104 const zoir = self.status.zoir orelse return null;102 if (self.index < self.diag.zoir.compile_errors.len) {
105103 const result: Error = .{ .zoir = self.diag.zoir.compile_errors[self.index] };
106 if (self.index < zoir.compile_errors.len) {
107 const result: Error = .{ .zoir = zoir.compile_errors[self.index] };
108 self.index += 1;104 self.index += 1;
109 return result;105 return result;
110 }106 }
111107
112 if (self.status.type_check) |err| {108 if (self.diag.type_check) |err| {
113 if (self.index == zoir.compile_errors.len) {109 if (self.index == self.diag.zoir.compile_errors.len) {
114 const result: Error = .{ .type_check = err };110 const result: Error = .{ .type_check = err };
115 self.index += 1;111 self.index += 1;
116 return result;112 return result;
...@@ -156,7 +152,7 @@ pub const Error = union(enum) {...@@ -156,7 +152,7 @@ pub const Error = union(enum) {
156152
157 const FormatMessage = struct {153 const FormatMessage = struct {
158 err: Error,154 err: Error,
159 status: *const Status,155 diag: *const Diagnostics,
160 };156 };
161157
162 fn formatMessage(158 fn formatMessage(
...@@ -168,32 +164,31 @@ pub const Error = union(enum) {...@@ -168,32 +164,31 @@ pub const Error = union(enum) {
168 _ = f;164 _ = f;
169 _ = options;165 _ = options;
170 switch (self.err) {166 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)),
172 .type_check => |tc| try writer.writeAll(tc.message),168 .type_check => |tc| try writer.writeAll(tc.message),
173 }169 }
174 }170 }
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) {
177 return .{ .data = .{173 return .{ .data = .{
178 .err = self,174 .err = self,
179 .status = status,175 .diag = diag,
180 } };176 } };
181 }177 }
182178
183 pub fn getLocation(self: @This(), status: *const Status) Ast.Location {179 pub fn getLocation(self: @This(), diag: *const Diagnostics) Ast.Location {
184 const ast = status.ast.?;
185 return switch (self) {180 return switch (self) {
186 .zoir => |err| return zoirErrorLocation(181 .zoir => |err| return zoirErrorLocation(
187 status.ast.?,182 diag.ast,
188 err.token,183 err.token,
189 err.node_or_offset,184 err.node_or_offset,
190 ),185 ),
191 .type_check => |err| return ast.tokenLocation(err.offset, err.token),186 .type_check => |err| return diag.ast.tokenLocation(err.offset, err.token),
192 };187 };
193 }188 }
194189
195 pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator {190 pub fn iterateNotes(self: @This(), diag: *const Diagnostics) Note.Iterator {
196 return .{ .err = self, .status = status };191 return .{ .err = self, .diag = diag };
197 }192 }
198193
199 fn zoirErrorLocation(ast: Ast, maybe_token: Ast.OptionalTokenIndex, node_or_offset: u32) Ast.Location {194 fn zoirErrorLocation(ast: Ast, maybe_token: Ast.OptionalTokenIndex, node_or_offset: u32) Ast.Location {
...@@ -210,26 +205,40 @@ pub const Error = union(enum) {...@@ -210,26 +205,40 @@ pub const Error = union(enum) {
210};205};
211206
212/// Information about the success or failure of a parse.207/// Information about the success or failure of a parse.
213pub const Status = struct {208pub const Diagnostics = struct {
214 ast: ?Ast = null,209 ast: Ast = .{
215 zoir: ?Zoir = null,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 },
216 type_check: ?Error.TypeCheckFailure = null,225 type_check: ?Error.TypeCheckFailure = null,
217226
218 fn assertEmpty(self: Status) void {227 fn assertEmpty(self: Diagnostics) void {
219 assert(self.ast == null);228 assert(self.ast.tokens.len == 0);
220 assert(self.zoir == null);229 assert(self.zoir.nodes.len == 0);
221 assert(self.type_check == null);230 assert(self.type_check == null);
222 }231 }
223232
224 pub fn deinit(self: *Status, gpa: Allocator) void {233 pub fn deinit(self: *Diagnostics, gpa: Allocator) void {
225 if (self.ast) |*ast| ast.deinit(gpa);234 self.ast.deinit(gpa);
226 if (self.zoir) |*zoir| zoir.deinit(gpa);235 self.zoir.deinit(gpa);
227 if (self.type_check) |tc| tc.deinit(gpa);236 if (self.type_check) |tc| tc.deinit(gpa);
228 self.* = undefined;237 self.* = undefined;
229 }238 }
230239
231 pub fn iterateErrors(self: *const Status) Error.Iterator {240 pub fn iterateErrors(self: *const Diagnostics) Error.Iterator {
232 return .{ .status = self };241 return .{ .diag = self };
233 }242 }
234243
235 pub fn format(244 pub fn format(
...@@ -266,7 +275,7 @@ pub const Status = struct {...@@ -266,7 +275,7 @@ pub const Status = struct {
266/// invalid or can not be deserialized into type `T`.275/// invalid or can not be deserialized into type `T`.
267///276///
268/// When the parser returns `error.ParseZon`, it will also store a human readable explanation in277/// 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 `.{}`.
270pub fn fromSlice(279pub fn fromSlice(
271 /// The type to deserialize into. May not be or contain any of the following types:280 /// The type to deserialize into. May not be or contain any of the following types:
272 /// * Any comptime-only type, except in a comptime field281 /// * Any comptime-only type, except in a comptime field
...@@ -283,22 +292,22 @@ pub fn fromSlice(...@@ -283,22 +292,22 @@ pub fn fromSlice(
283 T: type,292 T: type,
284 gpa: Allocator,293 gpa: Allocator,
285 source: [:0]const u8,294 source: [:0]const u8,
286 status: ?*Status,295 diag: ?*Diagnostics,
287 options: Options,296 options: Options,
288) error{ OutOfMemory, ParseZon }!T {297) error{ OutOfMemory, ParseZon }!T {
289 if (status) |s| s.assertEmpty();298 if (diag) |s| s.assertEmpty();
290299
291 var ast = try std.zig.Ast.parse(gpa, source, .zon);300 var ast = try std.zig.Ast.parse(gpa, source, .zon);
292 defer if (status == null) ast.deinit(gpa);301 defer if (diag == null) ast.deinit(gpa);
293 if (status) |s| s.ast = ast;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,304 // If there's no diagnostics, Zoir exists for the lifetime of this function. If there is a
296 // ownership is transferred to status.305 // diagnostics, ownership is transferred to diagnostics.
297 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });306 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.* = .{};309 if (diag) |s| s.* = .{};
301 return fromZoir(T, gpa, ast, zoir, status, options);310 return fromZoir(T, gpa, ast, zoir, diag, options);
302}311}
303312
304/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.313/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.
...@@ -307,10 +316,10 @@ pub fn fromZoir(...@@ -307,10 +316,10 @@ pub fn fromZoir(
307 gpa: Allocator,316 gpa: Allocator,
308 ast: Ast,317 ast: Ast,
309 zoir: Zoir,318 zoir: Zoir,
310 status: ?*Status,319 diag: ?*Diagnostics,
311 options: Options,320 options: Options,
312) error{ OutOfMemory, ParseZon }!T {321) error{ OutOfMemory, ParseZon }!T {
313 return fromZoirNode(T, gpa, ast, zoir, .root, status, options);322 return fromZoirNode(T, gpa, ast, zoir, .root, diag, options);
314}323}
315324
316/// Like `fromZoir`, but the parse starts on `node` instead of root.325/// Like `fromZoir`, but the parse starts on `node` instead of root.
...@@ -320,12 +329,12 @@ pub fn fromZoirNode(...@@ -320,12 +329,12 @@ pub fn fromZoirNode(
320 ast: Ast,329 ast: Ast,
321 zoir: Zoir,330 zoir: Zoir,
322 node: Zoir.Node.Index,331 node: Zoir.Node.Index,
323 status: ?*Status,332 diag: ?*Diagnostics,
324 options: Options,333 options: Options,
325) error{ OutOfMemory, ParseZon }!T {334) error{ OutOfMemory, ParseZon }!T {
326 comptime assert(canParseType(T));335 comptime assert(canParseType(T));
327336
328 if (status) |s| {337 if (diag) |s| {
329 s.assertEmpty();338 s.assertEmpty();
330 s.ast = ast;339 s.ast = ast;
331 s.zoir = zoir;340 s.zoir = zoir;
...@@ -340,7 +349,7 @@ pub fn fromZoirNode(...@@ -340,7 +349,7 @@ pub fn fromZoirNode(
340 .ast = ast,349 .ast = ast,
341 .zoir = zoir,350 .zoir = zoir,
342 .options = options,351 .options = options,
343 .status = status,352 .diag = diag,
344 };353 };
345354
346 return parser.parseExpr(T, node);355 return parser.parseExpr(T, node);
...@@ -421,7 +430,7 @@ const Parser = struct {...@@ -421,7 +430,7 @@ const Parser = struct {
421 gpa: Allocator,430 gpa: Allocator,
422 ast: Ast,431 ast: Ast,
423 zoir: Zoir,432 zoir: Zoir,
424 status: ?*Status,433 diag: ?*Diagnostics,
425 options: Options,434 options: Options,
426435
427 fn parseExpr(self: *@This(), T: type, node: Zoir.Node.Index) error{ ParseZon, OutOfMemory }!T {436 fn parseExpr(self: *@This(), T: type, node: Zoir.Node.Index) error{ ParseZon, OutOfMemory }!T {
...@@ -436,6 +445,10 @@ const Parser = struct {...@@ -436,6 +445,10 @@ const Parser = struct {
436 T: type,445 T: type,
437 node: Zoir.Node.Index,446 node: Zoir.Node.Index,
438 ) error{ ParseZon, OutOfMemory, WrongType }!T {447 ) error{ ParseZon, OutOfMemory, WrongType }!T {
448 if (T == Zoir.Node.Index) {
449 return node;
450 }
451
439 switch (@typeInfo(T)) {452 switch (@typeInfo(T)) {
440 .optional => |optional| if (node.get(self.zoir) == .null) {453 .optional => |optional| if (node.get(self.zoir) == .null) {
441 return null;454 return null;
...@@ -984,7 +997,7 @@ const Parser = struct {...@@ -984,7 +997,7 @@ const Parser = struct {
984 ) error{ OutOfMemory, ParseZon } {997 ) error{ OutOfMemory, ParseZon } {
985 @branchHint(.cold);998 @branchHint(.cold);
986 comptime assert(args.len > 0);999 comptime assert(args.len > 0);
987 if (self.status) |s| s.type_check = .{1000 if (self.diag) |s| s.type_check = .{
988 .token = token,1001 .token = token,
989 .offset = offset,1002 .offset = offset,
990 .message = std.fmt.allocPrint(self.gpa, fmt, args) catch |err| {1003 .message = std.fmt.allocPrint(self.gpa, fmt, args) catch |err| {
...@@ -1013,7 +1026,7 @@ const Parser = struct {...@@ -1013,7 +1026,7 @@ const Parser = struct {
1013 failure: Error.TypeCheckFailure,1026 failure: Error.TypeCheckFailure,
1014 ) error{ParseZon} {1027 ) error{ParseZon} {
1015 @branchHint(.cold);1028 @branchHint(.cold);
1016 if (self.status) |s| s.type_check = failure;1029 if (self.diag) |s| s.type_check = failure;
1017 return error.ParseZon;1030 return error.ParseZon;
1018 }1031 }
10191032
...@@ -1279,13 +1292,13 @@ test "std.zon requiresAllocator" {...@@ -1279,13 +1292,13 @@ test "std.zon requiresAllocator" {
12791292
1280test "std.zon ast errors" {1293test "std.zon ast errors" {
1281 const gpa = std.testing.allocator;1294 const gpa = std.testing.allocator;
1282 var status: Status = .{};1295 var diag: Diagnostics = .{};
1283 defer status.deinit(gpa);1296 defer diag.deinit(gpa);
1284 try std.testing.expectError(1297 try std.testing.expectError(
1285 error.ParseZon,1298 error.ParseZon,
1286 fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &status, .{}),1299 fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &diag, .{}),
1287 );1300 );
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});
1289}1302}
12901303
1291test "std.zon comments" {1304test "std.zon comments" {
...@@ -1298,17 +1311,17 @@ test "std.zon comments" {...@@ -1298,17 +1311,17 @@ test "std.zon comments" {
1298 , null, .{}));1311 , null, .{}));
12991312
1300 {1313 {
1301 var status: Status = .{};1314 var diag: Diagnostics = .{};
1302 defer status.deinit(gpa);1315 defer diag.deinit(gpa);
1303 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa,1316 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa,
1304 \\//! comment1317 \\//! comment
1305 \\10 // comment1318 \\10 // comment
1306 \\// comment1319 \\// comment
1307 , &status, .{}));1320 , &diag, .{}));
1308 try std.testing.expectFmt(1321 try std.testing.expectFmt(
1309 "1:1: error: expected expression, found 'a document comment'\n",1322 "1:1: error: expected expression, found 'a document comment'\n",
1310 "{}",1323 "{}",
1311 .{status},1324 .{diag},
1312 );1325 );
1313 }1326 }
1314}1327}
...@@ -1319,16 +1332,16 @@ test "std.zon failure/oom formatting" {...@@ -1319,16 +1332,16 @@ test "std.zon failure/oom formatting" {
1319 .fail_index = 0,1332 .fail_index = 0,
1320 .resize_fail_index = 0,1333 .resize_fail_index = 0,
1321 });1334 });
1322 var status: Status = .{};1335 var diag: Diagnostics = .{};
1323 defer status.deinit(gpa);1336 defer diag.deinit(gpa);
1324 try std.testing.expectError(error.OutOfMemory, fromSlice(1337 try std.testing.expectError(error.OutOfMemory, fromSlice(
1325 []const u8,1338 []const u8,
1326 failing_allocator.allocator(),1339 failing_allocator.allocator(),
1327 "\"foo\"",1340 "\"foo\"",
1328 &status,1341 &diag,
1329 .{},1342 .{},
1330 ));1343 ));
1331 try std.testing.expectFmt("", "{}", .{status});1344 try std.testing.expectFmt("", "{}", .{diag});
1332}1345}
13331346
1334test "std.zon fromSlice syntax error" {1347test "std.zon fromSlice syntax error" {
...@@ -1397,11 +1410,11 @@ test "std.zon unions" {...@@ -1397,11 +1410,11 @@ test "std.zon unions" {
1397 // Unknown field1410 // Unknown field
1398 {1411 {
1399 const Union = union { x: f32, y: f32 };1412 const Union = union { x: f32, y: f32 };
1400 var status: Status = .{};1413 var diag: Diagnostics = .{};
1401 defer status.deinit(gpa);1414 defer diag.deinit(gpa);
1402 try std.testing.expectError(1415 try std.testing.expectError(
1403 error.ParseZon,1416 error.ParseZon,
1404 fromSlice(Union, gpa, ".{.z=2.5}", &status, .{}),1417 fromSlice(Union, gpa, ".{.z=2.5}", &diag, .{}),
1405 );1418 );
1406 try std.testing.expectFmt(1419 try std.testing.expectFmt(
1407 \\1:4: error: unexpected field 'z'1420 \\1:4: error: unexpected field 'z'
...@@ -1409,78 +1422,78 @@ test "std.zon unions" {...@@ -1409,78 +1422,78 @@ test "std.zon unions" {
1409 \\1422 \\
1410 ,1423 ,
1411 "{}",1424 "{}",
1412 .{status},1425 .{diag},
1413 );1426 );
1414 }1427 }
14151428
1416 // Explicit void field1429 // Explicit void field
1417 {1430 {
1418 const Union = union(enum) { x: void };1431 const Union = union(enum) { x: void };
1419 var status: Status = .{};1432 var diag: Diagnostics = .{};
1420 defer status.deinit(gpa);1433 defer diag.deinit(gpa);
1421 try std.testing.expectError(1434 try std.testing.expectError(
1422 error.ParseZon,1435 error.ParseZon,
1423 fromSlice(Union, gpa, ".{.x=1}", &status, .{}),1436 fromSlice(Union, gpa, ".{.x=1}", &diag, .{}),
1424 );1437 );
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});
1426 }1439 }
14271440
1428 // Extra field1441 // Extra field
1429 {1442 {
1430 const Union = union { x: f32, y: bool };1443 const Union = union { x: f32, y: bool };
1431 var status: Status = .{};1444 var diag: Diagnostics = .{};
1432 defer status.deinit(gpa);1445 defer diag.deinit(gpa);
1433 try std.testing.expectError(1446 try std.testing.expectError(
1434 error.ParseZon,1447 error.ParseZon,
1435 fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &status, .{}),1448 fromSlice(Union, gpa, ".{.x = 1.5, .y = true}", &diag, .{}),
1436 );1449 );
1437 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});1450 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
1438 }1451 }
14391452
1440 // No fields1453 // No fields
1441 {1454 {
1442 const Union = union { x: f32, y: bool };1455 const Union = union { x: f32, y: bool };
1443 var status: Status = .{};1456 var diag: Diagnostics = .{};
1444 defer status.deinit(gpa);1457 defer diag.deinit(gpa);
1445 try std.testing.expectError(1458 try std.testing.expectError(
1446 error.ParseZon,1459 error.ParseZon,
1447 fromSlice(Union, gpa, ".{}", &status, .{}),1460 fromSlice(Union, gpa, ".{}", &diag, .{}),
1448 );1461 );
1449 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});1462 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
1450 }1463 }
14511464
1452 // Enum literals cannot coerce into untagged unions1465 // Enum literals cannot coerce into untagged unions
1453 {1466 {
1454 const Union = union { x: void };1467 const Union = union { x: void };
1455 var status: Status = .{};1468 var diag: Diagnostics = .{};
1456 defer status.deinit(gpa);1469 defer diag.deinit(gpa);
1457 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{}));1470 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{}));
1458 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});1471 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
1459 }1472 }
14601473
1461 // Unknown field for enum literal coercion1474 // Unknown field for enum literal coercion
1462 {1475 {
1463 const Union = union(enum) { x: void };1476 const Union = union(enum) { x: void };
1464 var status: Status = .{};1477 var diag: Diagnostics = .{};
1465 defer status.deinit(gpa);1478 defer diag.deinit(gpa);
1466 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &status, .{}));1479 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".y", &diag, .{}));
1467 try std.testing.expectFmt(1480 try std.testing.expectFmt(
1468 \\1:2: error: unexpected field 'y'1481 \\1:2: error: unexpected field 'y'
1469 \\1:2: note: supported: 'x'1482 \\1:2: note: supported: 'x'
1470 \\1483 \\
1471 ,1484 ,
1472 "{}",1485 "{}",
1473 .{status},1486 .{diag},
1474 );1487 );
1475 }1488 }
14761489
1477 // Non void field for enum literal coercion1490 // Non void field for enum literal coercion
1478 {1491 {
1479 const Union = union(enum) { x: f32 };1492 const Union = union(enum) { x: f32 };
1480 var status: Status = .{};1493 var diag: Diagnostics = .{};
1481 defer status.deinit(gpa);1494 defer diag.deinit(gpa);
1482 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &status, .{}));1495 try std.testing.expectError(error.ParseZon, fromSlice(Union, gpa, ".x", &diag, .{}));
1483 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{status});1496 try std.testing.expectFmt("1:2: error: expected union\n", "{}", .{diag});
1484 }1497 }
1485}1498}
14861499
...@@ -1525,11 +1538,11 @@ test "std.zon structs" {...@@ -1525,11 +1538,11 @@ test "std.zon structs" {
1525 // Unknown field1538 // Unknown field
1526 {1539 {
1527 const Vec2 = struct { x: f32, y: f32 };1540 const Vec2 = struct { x: f32, y: f32 };
1528 var status: Status = .{};1541 var diag: Diagnostics = .{};
1529 defer status.deinit(gpa);1542 defer diag.deinit(gpa);
1530 try std.testing.expectError(1543 try std.testing.expectError(
1531 error.ParseZon,1544 error.ParseZon,
1532 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}),1545 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),
1533 );1546 );
1534 try std.testing.expectFmt(1547 try std.testing.expectFmt(
1535 \\1:12: error: unexpected field 'z'1548 \\1:12: error: unexpected field 'z'
...@@ -1537,24 +1550,24 @@ test "std.zon structs" {...@@ -1537,24 +1550,24 @@ test "std.zon structs" {
1537 \\1550 \\
1538 ,1551 ,
1539 "{}",1552 "{}",
1540 .{status},1553 .{diag},
1541 );1554 );
1542 }1555 }
15431556
1544 // Duplicate field1557 // Duplicate field
1545 {1558 {
1546 const Vec2 = struct { x: f32, y: f32 };1559 const Vec2 = struct { x: f32, y: f32 };
1547 var status: Status = .{};1560 var diag: Diagnostics = .{};
1548 defer status.deinit(gpa);1561 defer diag.deinit(gpa);
1549 try std.testing.expectError(1562 try std.testing.expectError(
1550 error.ParseZon,1563 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, .{}),
1552 );1565 );
1553 try std.testing.expectFmt(1566 try std.testing.expectFmt(
1554 \\1:4: error: duplicate struct field name1567 \\1:4: error: duplicate struct field name
1555 \\1:12: note: duplicate name here1568 \\1:12: note: duplicate name here
1556 \\1569 \\
1557 , "{}", .{status});1570 , "{}", .{diag});
1558 }1571 }
15591572
1560 // Ignore unknown fields1573 // Ignore unknown fields
...@@ -1569,29 +1582,29 @@ test "std.zon structs" {...@@ -1569,29 +1582,29 @@ test "std.zon structs" {
1569 // Unknown field when struct has no fields (regression test)1582 // Unknown field when struct has no fields (regression test)
1570 {1583 {
1571 const Vec2 = struct {};1584 const Vec2 = struct {};
1572 var status: Status = .{};1585 var diag: Diagnostics = .{};
1573 defer status.deinit(gpa);1586 defer diag.deinit(gpa);
1574 try std.testing.expectError(1587 try std.testing.expectError(
1575 error.ParseZon,1588 error.ParseZon,
1576 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &status, .{}),1589 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),
1577 );1590 );
1578 try std.testing.expectFmt(1591 try std.testing.expectFmt(
1579 \\1:4: error: unexpected field 'x'1592 \\1:4: error: unexpected field 'x'
1580 \\1:4: note: none expected1593 \\1:4: note: none expected
1581 \\1594 \\
1582 , "{}", .{status});1595 , "{}", .{diag});
1583 }1596 }
15841597
1585 // Missing field1598 // Missing field
1586 {1599 {
1587 const Vec2 = struct { x: f32, y: f32 };1600 const Vec2 = struct { x: f32, y: f32 };
1588 var status: Status = .{};1601 var diag: Diagnostics = .{};
1589 defer status.deinit(gpa);1602 defer diag.deinit(gpa);
1590 try std.testing.expectError(1603 try std.testing.expectError(
1591 error.ParseZon,1604 error.ParseZon,
1592 fromSlice(Vec2, gpa, ".{.x=1.5}", &status, .{}),1605 fromSlice(Vec2, gpa, ".{.x=1.5}", &diag, .{}),
1593 );1606 );
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});
1595 }1608 }
15961609
1597 // Default field1610 // Default field
...@@ -1611,14 +1624,14 @@ test "std.zon structs" {...@@ -1611,14 +1624,14 @@ test "std.zon structs" {
1611 // Comptime field assignment1624 // Comptime field assignment
1612 {1625 {
1613 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };1626 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1614 var status: Status = .{};1627 var diag: Diagnostics = .{};
1615 defer status.deinit(gpa);1628 defer diag.deinit(gpa);
1616 const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &status, .{});1629 const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &diag, .{});
1617 try std.testing.expectError(error.ParseZon, parsed);1630 try std.testing.expectError(error.ParseZon, parsed);
1618 try std.testing.expectFmt(1631 try std.testing.expectFmt(
1619 \\1:18: error: cannot initialize comptime field1632 \\1:18: error: cannot initialize comptime field
1620 \\1633 \\
1621 , "{}", .{status});1634 , "{}", .{diag});
1622 }1635 }
16231636
1624 // Enum field (regression test, we were previously getting the field name in an1637 // Enum field (regression test, we were previously getting the field name in an
...@@ -1640,52 +1653,52 @@ test "std.zon structs" {...@@ -1640,52 +1653,52 @@ test "std.zon structs" {
1640 {1653 {
1641 // Structs1654 // Structs
1642 {1655 {
1643 var status: Status = .{};1656 var diag: Diagnostics = .{};
1644 defer status.deinit(gpa);1657 defer diag.deinit(gpa);
1645 const parsed = fromSlice(struct {}, gpa, "Empty{}", &status, .{});1658 const parsed = fromSlice(struct {}, gpa, "Empty{}", &diag, .{});
1646 try std.testing.expectError(error.ParseZon, parsed);1659 try std.testing.expectError(error.ParseZon, parsed);
1647 try std.testing.expectFmt(1660 try std.testing.expectFmt(
1648 \\1:1: error: types are not available in ZON1661 \\1:1: error: types are not available in ZON
1649 \\1:1: note: replace the type with '.'1662 \\1:1: note: replace the type with '.'
1650 \\1663 \\
1651 , "{}", .{status});1664 , "{}", .{diag});
1652 }1665 }
16531666
1654 // Arrays1667 // Arrays
1655 {1668 {
1656 var status: Status = .{};1669 var diag: Diagnostics = .{};
1657 defer status.deinit(gpa);1670 defer diag.deinit(gpa);
1658 const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &status, .{});1671 const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &diag, .{});
1659 try std.testing.expectError(error.ParseZon, parsed);1672 try std.testing.expectError(error.ParseZon, parsed);
1660 try std.testing.expectFmt(1673 try std.testing.expectFmt(
1661 \\1:1: error: types are not available in ZON1674 \\1:1: error: types are not available in ZON
1662 \\1:1: note: replace the type with '.'1675 \\1:1: note: replace the type with '.'
1663 \\1676 \\
1664 , "{}", .{status});1677 , "{}", .{diag});
1665 }1678 }
16661679
1667 // Slices1680 // Slices
1668 {1681 {
1669 var status: Status = .{};1682 var diag: Diagnostics = .{};
1670 defer status.deinit(gpa);1683 defer diag.deinit(gpa);
1671 const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &status, .{});1684 const parsed = fromSlice([]u8, gpa, "[]u8{1, 2, 3}", &diag, .{});
1672 try std.testing.expectError(error.ParseZon, parsed);1685 try std.testing.expectError(error.ParseZon, parsed);
1673 try std.testing.expectFmt(1686 try std.testing.expectFmt(
1674 \\1:1: error: types are not available in ZON1687 \\1:1: error: types are not available in ZON
1675 \\1:1: note: replace the type with '.'1688 \\1:1: note: replace the type with '.'
1676 \\1689 \\
1677 , "{}", .{status});1690 , "{}", .{diag});
1678 }1691 }
16791692
1680 // Tuples1693 // Tuples
1681 {1694 {
1682 var status: Status = .{};1695 var diag: Diagnostics = .{};
1683 defer status.deinit(gpa);1696 defer diag.deinit(gpa);
1684 const parsed = fromSlice(1697 const parsed = fromSlice(
1685 struct { u8, u8, u8 },1698 struct { u8, u8, u8 },
1686 gpa,1699 gpa,
1687 "Tuple{1, 2, 3}",1700 "Tuple{1, 2, 3}",
1688 &status,1701 &diag,
1689 .{},1702 .{},
1690 );1703 );
1691 try std.testing.expectError(error.ParseZon, parsed);1704 try std.testing.expectError(error.ParseZon, parsed);
...@@ -1693,20 +1706,20 @@ test "std.zon structs" {...@@ -1693,20 +1706,20 @@ test "std.zon structs" {
1693 \\1:1: error: types are not available in ZON1706 \\1:1: error: types are not available in ZON
1694 \\1:1: note: replace the type with '.'1707 \\1:1: note: replace the type with '.'
1695 \\1708 \\
1696 , "{}", .{status});1709 , "{}", .{diag});
1697 }1710 }
16981711
1699 // Nested1712 // Nested
1700 {1713 {
1701 var status: Status = .{};1714 var diag: Diagnostics = .{};
1702 defer status.deinit(gpa);1715 defer diag.deinit(gpa);
1703 const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &status, .{});1716 const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &diag, .{});
1704 try std.testing.expectError(error.ParseZon, parsed);1717 try std.testing.expectError(error.ParseZon, parsed);
1705 try std.testing.expectFmt(1718 try std.testing.expectFmt(
1706 \\1:9: error: types are not available in ZON1719 \\1:9: error: types are not available in ZON
1707 \\1:9: note: replace the type with '.'1720 \\1:9: note: replace the type with '.'
1708 \\1721 \\
1709 , "{}", .{status});1722 , "{}", .{diag});
1710 }1723 }
1711 }1724 }
1712}1725}
...@@ -1745,53 +1758,53 @@ test "std.zon tuples" {...@@ -1745,53 +1758,53 @@ test "std.zon tuples" {
1745 // Extra field1758 // Extra field
1746 {1759 {
1747 const Tuple = struct { f32, bool };1760 const Tuple = struct { f32, bool };
1748 var status: Status = .{};1761 var diag: Diagnostics = .{};
1749 defer status.deinit(gpa);1762 defer diag.deinit(gpa);
1750 try std.testing.expectError(1763 try std.testing.expectError(
1751 error.ParseZon,1764 error.ParseZon,
1752 fromSlice(Tuple, gpa, ".{0.5, true, 123}", &status, .{}),1765 fromSlice(Tuple, gpa, ".{0.5, true, 123}", &diag, .{}),
1753 );1766 );
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});
1755 }1768 }
17561769
1757 // Extra field1770 // Extra field
1758 {1771 {
1759 const Tuple = struct { f32, bool };1772 const Tuple = struct { f32, bool };
1760 var status: Status = .{};1773 var diag: Diagnostics = .{};
1761 defer status.deinit(gpa);1774 defer diag.deinit(gpa);
1762 try std.testing.expectError(1775 try std.testing.expectError(
1763 error.ParseZon,1776 error.ParseZon,
1764 fromSlice(Tuple, gpa, ".{0.5}", &status, .{}),1777 fromSlice(Tuple, gpa, ".{0.5}", &diag, .{}),
1765 );1778 );
1766 try std.testing.expectFmt(1779 try std.testing.expectFmt(
1767 "1:2: error: missing tuple field with index 1\n",1780 "1:2: error: missing tuple field with index 1\n",
1768 "{}",1781 "{}",
1769 .{status},1782 .{diag},
1770 );1783 );
1771 }1784 }
17721785
1773 // Tuple with unexpected field names1786 // Tuple with unexpected field names
1774 {1787 {
1775 const Tuple = struct { f32 };1788 const Tuple = struct { f32 };
1776 var status: Status = .{};1789 var diag: Diagnostics = .{};
1777 defer status.deinit(gpa);1790 defer diag.deinit(gpa);
1778 try std.testing.expectError(1791 try std.testing.expectError(
1779 error.ParseZon,1792 error.ParseZon,
1780 fromSlice(Tuple, gpa, ".{.foo = 10.0}", &status, .{}),1793 fromSlice(Tuple, gpa, ".{.foo = 10.0}", &diag, .{}),
1781 );1794 );
1782 try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{status});1795 try std.testing.expectFmt("1:2: error: expected tuple\n", "{}", .{diag});
1783 }1796 }
17841797
1785 // Struct with missing field names1798 // Struct with missing field names
1786 {1799 {
1787 const Struct = struct { foo: f32 };1800 const Struct = struct { foo: f32 };
1788 var status: Status = .{};1801 var diag: Diagnostics = .{};
1789 defer status.deinit(gpa);1802 defer diag.deinit(gpa);
1790 try std.testing.expectError(1803 try std.testing.expectError(
1791 error.ParseZon,1804 error.ParseZon,
1792 fromSlice(Struct, gpa, ".{10.0}", &status, .{}),1805 fromSlice(Struct, gpa, ".{10.0}", &diag, .{}),
1793 );1806 );
1794 try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{status});1807 try std.testing.expectFmt("1:2: error: expected struct\n", "{}", .{diag});
1795 }1808 }
17961809
1797 // Comptime field1810 // Comptime field
...@@ -1804,14 +1817,14 @@ test "std.zon tuples" {...@@ -1804,14 +1817,14 @@ test "std.zon tuples" {
1804 // Comptime field assignment1817 // Comptime field assignment
1805 {1818 {
1806 const Vec2 = struct { f32, comptime f32 = 1.5 };1819 const Vec2 = struct { f32, comptime f32 = 1.5 };
1807 var status: Status = .{};1820 var diag: Diagnostics = .{};
1808 defer status.deinit(gpa);1821 defer diag.deinit(gpa);
1809 const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &status, .{});1822 const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &diag, .{});
1810 try std.testing.expectError(error.ParseZon, parsed);1823 try std.testing.expectError(error.ParseZon, parsed);
1811 try std.testing.expectFmt(1824 try std.testing.expectFmt(
1812 \\1:9: error: cannot initialize comptime field1825 \\1:9: error: cannot initialize comptime field
1813 \\1826 \\
1814 , "{}", .{status});1827 , "{}", .{diag});
1815 }1828 }
1816}1829}
18171830
...@@ -1915,61 +1928,61 @@ test "std.zon arrays and slices" {...@@ -1915,61 +1928,61 @@ test "std.zon arrays and slices" {
19151928
1916 // Expect 0 find 31929 // Expect 0 find 3
1917 {1930 {
1918 var status: Status = .{};1931 var diag: Diagnostics = .{};
1919 defer status.deinit(gpa);1932 defer diag.deinit(gpa);
1920 try std.testing.expectError(1933 try std.testing.expectError(
1921 error.ParseZon,1934 error.ParseZon,
1922 fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &status, .{}),1935 fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
1923 );1936 );
1924 try std.testing.expectFmt(1937 try std.testing.expectFmt(
1925 "1:3: error: index 0 outside of array of length 0\n",1938 "1:3: error: index 0 outside of array of length 0\n",
1926 "{}",1939 "{}",
1927 .{status},1940 .{diag},
1928 );1941 );
1929 }1942 }
19301943
1931 // Expect 1 find 21944 // Expect 1 find 2
1932 {1945 {
1933 var status: Status = .{};1946 var diag: Diagnostics = .{};
1934 defer status.deinit(gpa);1947 defer diag.deinit(gpa);
1935 try std.testing.expectError(1948 try std.testing.expectError(
1936 error.ParseZon,1949 error.ParseZon,
1937 fromSlice([1]u8, gpa, ".{'a', 'b'}", &status, .{}),1950 fromSlice([1]u8, gpa, ".{'a', 'b'}", &diag, .{}),
1938 );1951 );
1939 try std.testing.expectFmt(1952 try std.testing.expectFmt(
1940 "1:8: error: index 1 outside of array of length 1\n",1953 "1:8: error: index 1 outside of array of length 1\n",
1941 "{}",1954 "{}",
1942 .{status},1955 .{diag},
1943 );1956 );
1944 }1957 }
19451958
1946 // Expect 2 find 11959 // Expect 2 find 1
1947 {1960 {
1948 var status: Status = .{};1961 var diag: Diagnostics = .{};
1949 defer status.deinit(gpa);1962 defer diag.deinit(gpa);
1950 try std.testing.expectError(1963 try std.testing.expectError(
1951 error.ParseZon,1964 error.ParseZon,
1952 fromSlice([2]u8, gpa, ".{'a'}", &status, .{}),1965 fromSlice([2]u8, gpa, ".{'a'}", &diag, .{}),
1953 );1966 );
1954 try std.testing.expectFmt(1967 try std.testing.expectFmt(
1955 "1:2: error: expected 2 array elements; found 1\n",1968 "1:2: error: expected 2 array elements; found 1\n",
1956 "{}",1969 "{}",
1957 .{status},1970 .{diag},
1958 );1971 );
1959 }1972 }
19601973
1961 // Expect 3 find 01974 // Expect 3 find 0
1962 {1975 {
1963 var status: Status = .{};1976 var diag: Diagnostics = .{};
1964 defer status.deinit(gpa);1977 defer diag.deinit(gpa);
1965 try std.testing.expectError(1978 try std.testing.expectError(
1966 error.ParseZon,1979 error.ParseZon,
1967 fromSlice([3]u8, gpa, ".{}", &status, .{}),1980 fromSlice([3]u8, gpa, ".{}", &diag, .{}),
1968 );1981 );
1969 try std.testing.expectFmt(1982 try std.testing.expectFmt(
1970 "1:2: error: expected 3 array elements; found 0\n",1983 "1:2: error: expected 3 array elements; found 0\n",
1971 "{}",1984 "{}",
1972 .{status},1985 .{diag},
1973 );1986 );
1974 }1987 }
19751988
...@@ -1977,24 +1990,24 @@ test "std.zon arrays and slices" {...@@ -1977,24 +1990,24 @@ test "std.zon arrays and slices" {
1977 {1990 {
1978 // Array1991 // Array
1979 {1992 {
1980 var status: Status = .{};1993 var diag: Diagnostics = .{};
1981 defer status.deinit(gpa);1994 defer diag.deinit(gpa);
1982 try std.testing.expectError(1995 try std.testing.expectError(
1983 error.ParseZon,1996 error.ParseZon,
1984 fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}),1997 fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
1985 );1998 );
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});
1987 }2000 }
19882001
1989 // Slice2002 // Slice
1990 {2003 {
1991 var status: Status = .{};2004 var diag: Diagnostics = .{};
1992 defer status.deinit(gpa);2005 defer diag.deinit(gpa);
1993 try std.testing.expectError(2006 try std.testing.expectError(
1994 error.ParseZon,2007 error.ParseZon,
1995 fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &status, .{}),2008 fromSlice([]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),
1996 );2009 );
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});
1998 }2011 }
1999 }2012 }
20002013
...@@ -2002,39 +2015,39 @@ test "std.zon arrays and slices" {...@@ -2002,39 +2015,39 @@ test "std.zon arrays and slices" {
2002 {2015 {
2003 // Array2016 // Array
2004 {2017 {
2005 var status: Status = .{};2018 var diag: Diagnostics = .{};
2006 defer status.deinit(gpa);2019 defer diag.deinit(gpa);
2007 try std.testing.expectError(2020 try std.testing.expectError(
2008 error.ParseZon,2021 error.ParseZon,
2009 fromSlice([3]u8, gpa, "'a'", &status, .{}),2022 fromSlice([3]u8, gpa, "'a'", &diag, .{}),
2010 );2023 );
2011 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2024 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2012 }2025 }
20132026
2014 // Slice2027 // Slice
2015 {2028 {
2016 var status: Status = .{};2029 var diag: Diagnostics = .{};
2017 defer status.deinit(gpa);2030 defer diag.deinit(gpa);
2018 try std.testing.expectError(2031 try std.testing.expectError(
2019 error.ParseZon,2032 error.ParseZon,
2020 fromSlice([]u8, gpa, "'a'", &status, .{}),2033 fromSlice([]u8, gpa, "'a'", &diag, .{}),
2021 );2034 );
2022 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2035 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2023 }2036 }
2024 }2037 }
20252038
2026 // Address of is not allowed (indirection for slices in ZON is implicit)2039 // Address of is not allowed (indirection for slices in ZON is implicit)
2027 {2040 {
2028 var status: Status = .{};2041 var diag: Diagnostics = .{};
2029 defer status.deinit(gpa);2042 defer diag.deinit(gpa);
2030 try std.testing.expectError(2043 try std.testing.expectError(
2031 error.ParseZon,2044 error.ParseZon,
2032 fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &status, .{}),2045 fromSlice([]u8, gpa, " &.{'a', 'b', 'c'}", &diag, .{}),
2033 );2046 );
2034 try std.testing.expectFmt(2047 try std.testing.expectFmt(
2035 "1:3: error: pointers are not available in ZON\n",2048 "1:3: error: pointers are not available in ZON\n",
2036 "{}",2049 "{}",
2037 .{status},2050 .{diag},
2038 );2051 );
2039 }2052 }
2040}2053}
...@@ -2066,23 +2079,23 @@ test "std.zon string literal" {...@@ -2066,23 +2079,23 @@ test "std.zon string literal" {
2066 // Passing string literal to a mutable slice2079 // Passing string literal to a mutable slice
2067 {2080 {
2068 {2081 {
2069 var status: Status = .{};2082 var diag: Diagnostics = .{};
2070 defer status.deinit(gpa);2083 defer diag.deinit(gpa);
2071 try std.testing.expectError(2084 try std.testing.expectError(
2072 error.ParseZon,2085 error.ParseZon,
2073 fromSlice([]u8, gpa, "\"abcd\"", &status, .{}),2086 fromSlice([]u8, gpa, "\"abcd\"", &diag, .{}),
2074 );2087 );
2075 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2088 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2076 }2089 }
20772090
2078 {2091 {
2079 var status: Status = .{};2092 var diag: Diagnostics = .{};
2080 defer status.deinit(gpa);2093 defer diag.deinit(gpa);
2081 try std.testing.expectError(2094 try std.testing.expectError(
2082 error.ParseZon,2095 error.ParseZon,
2083 fromSlice([]u8, gpa, "\\\\abcd", &status, .{}),2096 fromSlice([]u8, gpa, "\\\\abcd", &diag, .{}),
2084 );2097 );
2085 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2098 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2086 }2099 }
2087 }2100 }
20882101
...@@ -2093,23 +2106,23 @@ test "std.zon string literal" {...@@ -2093,23 +2106,23 @@ test "std.zon string literal" {
2093 defer ast.deinit(gpa);2106 defer ast.deinit(gpa);
2094 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });2107 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
2095 defer zoir.deinit(gpa);2108 defer zoir.deinit(gpa);
2096 var status: Status = .{};2109 var diag: Diagnostics = .{};
2097 defer status.deinit(gpa);2110 defer diag.deinit(gpa);
2098 try std.testing.expectError(2111 try std.testing.expectError(
2099 error.ParseZon,2112 error.ParseZon,
2100 fromSlice([4:0]u8, gpa, "\"abcd\"", &status, .{}),2113 fromSlice([4:0]u8, gpa, "\"abcd\"", &diag, .{}),
2101 );2114 );
2102 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2115 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2103 }2116 }
21042117
2105 {2118 {
2106 var status: Status = .{};2119 var diag: Diagnostics = .{};
2107 defer status.deinit(gpa);2120 defer diag.deinit(gpa);
2108 try std.testing.expectError(2121 try std.testing.expectError(
2109 error.ParseZon,2122 error.ParseZon,
2110 fromSlice([4:0]u8, gpa, "\\\\abcd", &status, .{}),2123 fromSlice([4:0]u8, gpa, "\\\\abcd", &diag, .{}),
2111 );2124 );
2112 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2125 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2113 }2126 }
2114 }2127 }
21152128
...@@ -2145,102 +2158,102 @@ test "std.zon string literal" {...@@ -2145,102 +2158,102 @@ test "std.zon string literal" {
2145 // Other value terminated slices2158 // Other value terminated slices
2146 {2159 {
2147 {2160 {
2148 var status: Status = .{};2161 var diag: Diagnostics = .{};
2149 defer status.deinit(gpa);2162 defer diag.deinit(gpa);
2150 try std.testing.expectError(2163 try std.testing.expectError(
2151 error.ParseZon,2164 error.ParseZon,
2152 fromSlice([:1]const u8, gpa, "\"foo\"", &status, .{}),2165 fromSlice([:1]const u8, gpa, "\"foo\"", &diag, .{}),
2153 );2166 );
2154 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2167 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2155 }2168 }
21562169
2157 {2170 {
2158 var status: Status = .{};2171 var diag: Diagnostics = .{};
2159 defer status.deinit(gpa);2172 defer diag.deinit(gpa);
2160 try std.testing.expectError(2173 try std.testing.expectError(
2161 error.ParseZon,2174 error.ParseZon,
2162 fromSlice([:1]const u8, gpa, "\\\\foo", &status, .{}),2175 fromSlice([:1]const u8, gpa, "\\\\foo", &diag, .{}),
2163 );2176 );
2164 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2177 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2165 }2178 }
2166 }2179 }
21672180
2168 // Expecting string literal, getting something else2181 // Expecting string literal, getting something else
2169 {2182 {
2170 var status: Status = .{};2183 var diag: Diagnostics = .{};
2171 defer status.deinit(gpa);2184 defer diag.deinit(gpa);
2172 try std.testing.expectError(2185 try std.testing.expectError(
2173 error.ParseZon,2186 error.ParseZon,
2174 fromSlice([]const u8, gpa, "true", &status, .{}),2187 fromSlice([]const u8, gpa, "true", &diag, .{}),
2175 );2188 );
2176 try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{status});2189 try std.testing.expectFmt("1:1: error: expected string\n", "{}", .{diag});
2177 }2190 }
21782191
2179 // Expecting string literal, getting an incompatible tuple2192 // Expecting string literal, getting an incompatible tuple
2180 {2193 {
2181 var status: Status = .{};2194 var diag: Diagnostics = .{};
2182 defer status.deinit(gpa);2195 defer diag.deinit(gpa);
2183 try std.testing.expectError(2196 try std.testing.expectError(
2184 error.ParseZon,2197 error.ParseZon,
2185 fromSlice([]const u8, gpa, ".{false}", &status, .{}),2198 fromSlice([]const u8, gpa, ".{false}", &diag, .{}),
2186 );2199 );
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});
2188 }2201 }
21892202
2190 // Invalid string literal2203 // Invalid string literal
2191 {2204 {
2192 var status: Status = .{};2205 var diag: Diagnostics = .{};
2193 defer status.deinit(gpa);2206 defer diag.deinit(gpa);
2194 try std.testing.expectError(2207 try std.testing.expectError(
2195 error.ParseZon,2208 error.ParseZon,
2196 fromSlice([]const i8, gpa, "\"\\a\"", &status, .{}),2209 fromSlice([]const i8, gpa, "\"\\a\"", &diag, .{}),
2197 );2210 );
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});
2199 }2212 }
22002213
2201 // Slice wrong child type2214 // Slice wrong child type
2202 {2215 {
2203 {2216 {
2204 var status: Status = .{};2217 var diag: Diagnostics = .{};
2205 defer status.deinit(gpa);2218 defer diag.deinit(gpa);
2206 try std.testing.expectError(2219 try std.testing.expectError(
2207 error.ParseZon,2220 error.ParseZon,
2208 fromSlice([]const i8, gpa, "\"a\"", &status, .{}),2221 fromSlice([]const i8, gpa, "\"a\"", &diag, .{}),
2209 );2222 );
2210 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2223 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2211 }2224 }
22122225
2213 {2226 {
2214 var status: Status = .{};2227 var diag: Diagnostics = .{};
2215 defer status.deinit(gpa);2228 defer diag.deinit(gpa);
2216 try std.testing.expectError(2229 try std.testing.expectError(
2217 error.ParseZon,2230 error.ParseZon,
2218 fromSlice([]const i8, gpa, "\\\\a", &status, .{}),2231 fromSlice([]const i8, gpa, "\\\\a", &diag, .{}),
2219 );2232 );
2220 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2233 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2221 }2234 }
2222 }2235 }
22232236
2224 // Bad alignment2237 // Bad alignment
2225 {2238 {
2226 {2239 {
2227 var status: Status = .{};2240 var diag: Diagnostics = .{};
2228 defer status.deinit(gpa);2241 defer diag.deinit(gpa);
2229 try std.testing.expectError(2242 try std.testing.expectError(
2230 error.ParseZon,2243 error.ParseZon,
2231 fromSlice([]align(2) const u8, gpa, "\"abc\"", &status, .{}),2244 fromSlice([]align(2) const u8, gpa, "\"abc\"", &diag, .{}),
2232 );2245 );
2233 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2246 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2234 }2247 }
22352248
2236 {2249 {
2237 var status: Status = .{};2250 var diag: Diagnostics = .{};
2238 defer status.deinit(gpa);2251 defer diag.deinit(gpa);
2239 try std.testing.expectError(2252 try std.testing.expectError(
2240 error.ParseZon,2253 error.ParseZon,
2241 fromSlice([]align(2) const u8, gpa, "\\\\abc", &status, .{}),2254 fromSlice([]align(2) const u8, gpa, "\\\\abc", &diag, .{}),
2242 );2255 );
2243 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{status});2256 try std.testing.expectFmt("1:1: error: expected array\n", "{}", .{diag});
2244 }2257 }
2245 }2258 }
22462259
...@@ -2303,11 +2316,11 @@ test "std.zon enum literals" {...@@ -2303,11 +2316,11 @@ test "std.zon enum literals" {
23032316
2304 // Bad tag2317 // Bad tag
2305 {2318 {
2306 var status: Status = .{};2319 var diag: Diagnostics = .{};
2307 defer status.deinit(gpa);2320 defer diag.deinit(gpa);
2308 try std.testing.expectError(2321 try std.testing.expectError(
2309 error.ParseZon,2322 error.ParseZon,
2310 fromSlice(Enum, gpa, ".qux", &status, .{}),2323 fromSlice(Enum, gpa, ".qux", &diag, .{}),
2311 );2324 );
2312 try std.testing.expectFmt(2325 try std.testing.expectFmt(
2313 \\1:2: error: unexpected enum literal 'qux'2326 \\1:2: error: unexpected enum literal 'qux'
...@@ -2315,17 +2328,17 @@ test "std.zon enum literals" {...@@ -2315,17 +2328,17 @@ test "std.zon enum literals" {
2315 \\2328 \\
2316 ,2329 ,
2317 "{}",2330 "{}",
2318 .{status},2331 .{diag},
2319 );2332 );
2320 }2333 }
23212334
2322 // Bad tag that's too long for parser2335 // Bad tag that's too long for parser
2323 {2336 {
2324 var status: Status = .{};2337 var diag: Diagnostics = .{};
2325 defer status.deinit(gpa);2338 defer diag.deinit(gpa);
2326 try std.testing.expectError(2339 try std.testing.expectError(
2327 error.ParseZon,2340 error.ParseZon,
2328 fromSlice(Enum, gpa, ".@\"foobarbaz\"", &status, .{}),2341 fromSlice(Enum, gpa, ".@\"foobarbaz\"", &diag, .{}),
2329 );2342 );
2330 try std.testing.expectFmt(2343 try std.testing.expectFmt(
2331 \\1:2: error: unexpected enum literal 'foobarbaz'2344 \\1:2: error: unexpected enum literal 'foobarbaz'
...@@ -2333,33 +2346,33 @@ test "std.zon enum literals" {...@@ -2333,33 +2346,33 @@ test "std.zon enum literals" {
2333 \\2346 \\
2334 ,2347 ,
2335 "{}",2348 "{}",
2336 .{status},2349 .{diag},
2337 );2350 );
2338 }2351 }
23392352
2340 // Bad type2353 // Bad type
2341 {2354 {
2342 var status: Status = .{};2355 var diag: Diagnostics = .{};
2343 defer status.deinit(gpa);2356 defer diag.deinit(gpa);
2344 try std.testing.expectError(2357 try std.testing.expectError(
2345 error.ParseZon,2358 error.ParseZon,
2346 fromSlice(Enum, gpa, "true", &status, .{}),2359 fromSlice(Enum, gpa, "true", &diag, .{}),
2347 );2360 );
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});
2349 }2362 }
23502363
2351 // Test embedded nulls in an identifier2364 // Test embedded nulls in an identifier
2352 {2365 {
2353 var status: Status = .{};2366 var diag: Diagnostics = .{};
2354 defer status.deinit(gpa);2367 defer diag.deinit(gpa);
2355 try std.testing.expectError(2368 try std.testing.expectError(
2356 error.ParseZon,2369 error.ParseZon,
2357 fromSlice(Enum, gpa, ".@\"\\x00\"", &status, .{}),2370 fromSlice(Enum, gpa, ".@\"\\x00\"", &diag, .{}),
2358 );2371 );
2359 try std.testing.expectFmt(2372 try std.testing.expectFmt(
2360 "1:2: error: identifier cannot contain null bytes\n",2373 "1:2: error: identifier cannot contain null bytes\n",
2361 "{}",2374 "{}",
2362 .{status},2375 .{diag},
2363 );2376 );
2364 }2377 }
2365}2378}
...@@ -2373,24 +2386,24 @@ test "std.zon parse bool" {...@@ -2373,24 +2386,24 @@ test "std.zon parse bool" {
23732386
2374 // Errors2387 // Errors
2375 {2388 {
2376 var status: Status = .{};2389 var diag: Diagnostics = .{};
2377 defer status.deinit(gpa);2390 defer diag.deinit(gpa);
2378 try std.testing.expectError(2391 try std.testing.expectError(
2379 error.ParseZon,2392 error.ParseZon,
2380 fromSlice(bool, gpa, " foo", &status, .{}),2393 fromSlice(bool, gpa, " foo", &diag, .{}),
2381 );2394 );
2382 try std.testing.expectFmt(2395 try std.testing.expectFmt(
2383 \\1:2: error: invalid expression2396 \\1:2: error: invalid expression
2384 \\1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'2397 \\1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
2385 \\1:2: note: precede identifier with '.' for an enum literal2398 \\1:2: note: precede identifier with '.' for an enum literal
2386 \\2399 \\
2387 , "{}", .{status});2400 , "{}", .{diag});
2388 }2401 }
2389 {2402 {
2390 var status: Status = .{};2403 var diag: Diagnostics = .{};
2391 defer status.deinit(gpa);2404 defer diag.deinit(gpa);
2392 try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &status, .{}));2405 try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &diag, .{}));
2393 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{status});2406 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{}", .{diag});
2394 }2407 }
2395}2408}
23962409
...@@ -2452,35 +2465,35 @@ test "std.zon parse int" {...@@ -2452,35 +2465,35 @@ test "std.zon parse int" {
2452 try fromSlice(i66, gpa, "-36893488147419103232", null, .{}),2465 try fromSlice(i66, gpa, "-36893488147419103232", null, .{}),
2453 );2466 );
2454 {2467 {
2455 var status: Status = .{};2468 var diag: Diagnostics = .{};
2456 defer status.deinit(gpa);2469 defer diag.deinit(gpa);
2457 try std.testing.expectError(error.ParseZon, fromSlice(2470 try std.testing.expectError(error.ParseZon, fromSlice(
2458 i66,2471 i66,
2459 gpa,2472 gpa,
2460 "36893488147419103232",2473 "36893488147419103232",
2461 &status,2474 &diag,
2462 .{},2475 .{},
2463 ));2476 ));
2464 try std.testing.expectFmt(2477 try std.testing.expectFmt(
2465 "1:1: error: type 'i66' cannot represent value\n",2478 "1:1: error: type 'i66' cannot represent value\n",
2466 "{}",2479 "{}",
2467 .{status},2480 .{diag},
2468 );2481 );
2469 }2482 }
2470 {2483 {
2471 var status: Status = .{};2484 var diag: Diagnostics = .{};
2472 defer status.deinit(gpa);2485 defer diag.deinit(gpa);
2473 try std.testing.expectError(error.ParseZon, fromSlice(2486 try std.testing.expectError(error.ParseZon, fromSlice(
2474 i66,2487 i66,
2475 gpa,2488 gpa,
2476 "-36893488147419103233",2489 "-36893488147419103233",
2477 &status,2490 &diag,
2478 .{},2491 .{},
2479 ));2492 ));
2480 try std.testing.expectFmt(2493 try std.testing.expectFmt(
2481 "1:1: error: type 'i66' cannot represent value\n",2494 "1:1: error: type 'i66' cannot represent value\n",
2482 "{}",2495 "{}",
2483 .{status},2496 .{diag},
2484 );2497 );
2485 }2498 }
24862499
...@@ -2563,108 +2576,108 @@ test "std.zon parse int" {...@@ -2563,108 +2576,108 @@ test "std.zon parse int" {
25632576
2564 // Number with invalid character in the middle2577 // Number with invalid character in the middle
2565 {2578 {
2566 var status: Status = .{};2579 var diag: Diagnostics = .{};
2567 defer status.deinit(gpa);2580 defer diag.deinit(gpa);
2568 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &status, .{}));2581 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &diag, .{}));
2569 try std.testing.expectFmt(2582 try std.testing.expectFmt(
2570 "1:3: error: invalid digit 'a' for decimal base\n",2583 "1:3: error: invalid digit 'a' for decimal base\n",
2571 "{}",2584 "{}",
2572 .{status},2585 .{diag},
2573 );2586 );
2574 }2587 }
25752588
2576 // Failing to parse as int2589 // Failing to parse as int
2577 {2590 {
2578 var status: Status = .{};2591 var diag: Diagnostics = .{};
2579 defer status.deinit(gpa);2592 defer diag.deinit(gpa);
2580 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &status, .{}));2593 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &diag, .{}));
2581 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{status});2594 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{}", .{diag});
2582 }2595 }
25832596
2584 // Failing because an int is out of range2597 // Failing because an int is out of range
2585 {2598 {
2586 var status: Status = .{};2599 var diag: Diagnostics = .{};
2587 defer status.deinit(gpa);2600 defer diag.deinit(gpa);
2588 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &status, .{}));2601 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &diag, .{}));
2589 try std.testing.expectFmt(2602 try std.testing.expectFmt(
2590 "1:1: error: type 'u8' cannot represent value\n",2603 "1:1: error: type 'u8' cannot represent value\n",
2591 "{}",2604 "{}",
2592 .{status},2605 .{diag},
2593 );2606 );
2594 }2607 }
25952608
2596 // Failing because a negative int is out of range2609 // Failing because a negative int is out of range
2597 {2610 {
2598 var status: Status = .{};2611 var diag: Diagnostics = .{};
2599 defer status.deinit(gpa);2612 defer diag.deinit(gpa);
2600 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &status, .{}));2613 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &diag, .{}));
2601 try std.testing.expectFmt(2614 try std.testing.expectFmt(
2602 "1:1: error: type 'i8' cannot represent value\n",2615 "1:1: error: type 'i8' cannot represent value\n",
2603 "{}",2616 "{}",
2604 .{status},2617 .{diag},
2605 );2618 );
2606 }2619 }
26072620
2608 // Failing because an unsigned int is negative2621 // Failing because an unsigned int is negative
2609 {2622 {
2610 var status: Status = .{};2623 var diag: Diagnostics = .{};
2611 defer status.deinit(gpa);2624 defer diag.deinit(gpa);
2612 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &status, .{}));2625 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &diag, .{}));
2613 try std.testing.expectFmt(2626 try std.testing.expectFmt(
2614 "1:1: error: type 'u8' cannot represent value\n",2627 "1:1: error: type 'u8' cannot represent value\n",
2615 "{}",2628 "{}",
2616 .{status},2629 .{diag},
2617 );2630 );
2618 }2631 }
26192632
2620 // Failing because a float is non-whole2633 // Failing because a float is non-whole
2621 {2634 {
2622 var status: Status = .{};2635 var diag: Diagnostics = .{};
2623 defer status.deinit(gpa);2636 defer diag.deinit(gpa);
2624 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &status, .{}));2637 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &diag, .{}));
2625 try std.testing.expectFmt(2638 try std.testing.expectFmt(
2626 "1:1: error: type 'u8' cannot represent value\n",2639 "1:1: error: type 'u8' cannot represent value\n",
2627 "{}",2640 "{}",
2628 .{status},2641 .{diag},
2629 );2642 );
2630 }2643 }
26312644
2632 // Failing because a float is negative2645 // Failing because a float is negative
2633 {2646 {
2634 var status: Status = .{};2647 var diag: Diagnostics = .{};
2635 defer status.deinit(gpa);2648 defer diag.deinit(gpa);
2636 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &status, .{}));2649 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &diag, .{}));
2637 try std.testing.expectFmt(2650 try std.testing.expectFmt(
2638 "1:1: error: type 'u8' cannot represent value\n",2651 "1:1: error: type 'u8' cannot represent value\n",
2639 "{}",2652 "{}",
2640 .{status},2653 .{diag},
2641 );2654 );
2642 }2655 }
26432656
2644 // Negative integer zero2657 // Negative integer zero
2645 {2658 {
2646 var status: Status = .{};2659 var diag: Diagnostics = .{};
2647 defer status.deinit(gpa);2660 defer diag.deinit(gpa);
2648 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &status, .{}));2661 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &diag, .{}));
2649 try std.testing.expectFmt(2662 try std.testing.expectFmt(
2650 \\1:2: error: integer literal '-0' is ambiguous2663 \\1:2: error: integer literal '-0' is ambiguous
2651 \\1:2: note: use '0' for an integer zero2664 \\1:2: note: use '0' for an integer zero
2652 \\1:2: note: use '-0.0' for a floating-point signed zero2665 \\1:2: note: use '-0.0' for a floating-point signed zero
2653 \\2666 \\
2654 , "{}", .{status});2667 , "{}", .{diag});
2655 }2668 }
26562669
2657 // Negative integer zero casted to float2670 // Negative integer zero casted to float
2658 {2671 {
2659 var status: Status = .{};2672 var diag: Diagnostics = .{};
2660 defer status.deinit(gpa);2673 defer diag.deinit(gpa);
2661 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &status, .{}));2674 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &diag, .{}));
2662 try std.testing.expectFmt(2675 try std.testing.expectFmt(
2663 \\1:2: error: integer literal '-0' is ambiguous2676 \\1:2: error: integer literal '-0' is ambiguous
2664 \\1:2: note: use '0' for an integer zero2677 \\1:2: note: use '0' for an integer zero
2665 \\1:2: note: use '-0.0' for a floating-point signed zero2678 \\1:2: note: use '-0.0' for a floating-point signed zero
2666 \\2679 \\
2667 , "{}", .{status});2680 , "{}", .{diag});
2668 }2681 }
26692682
2670 // Negative float 0 is allowed2683 // Negative float 0 is allowed
...@@ -2675,48 +2688,48 @@ test "std.zon parse int" {...@@ -2675,48 +2688,48 @@ test "std.zon parse int" {
26752688
2676 // Double negation is not allowed2689 // Double negation is not allowed
2677 {2690 {
2678 var status: Status = .{};2691 var diag: Diagnostics = .{};
2679 defer status.deinit(gpa);2692 defer diag.deinit(gpa);
2680 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &status, .{}));2693 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &diag, .{}));
2681 try std.testing.expectFmt(2694 try std.testing.expectFmt(
2682 "1:1: error: expected number or 'inf' after '-'\n",2695 "1:1: error: expected number or 'inf' after '-'\n",
2683 "{}",2696 "{}",
2684 .{status},2697 .{diag},
2685 );2698 );
2686 }2699 }
26872700
2688 {2701 {
2689 var status: Status = .{};2702 var diag: Diagnostics = .{};
2690 defer status.deinit(gpa);2703 defer diag.deinit(gpa);
2691 try std.testing.expectError(2704 try std.testing.expectError(
2692 error.ParseZon,2705 error.ParseZon,
2693 fromSlice(f32, gpa, "--2.0", &status, .{}),2706 fromSlice(f32, gpa, "--2.0", &diag, .{}),
2694 );2707 );
2695 try std.testing.expectFmt(2708 try std.testing.expectFmt(
2696 "1:1: error: expected number or 'inf' after '-'\n",2709 "1:1: error: expected number or 'inf' after '-'\n",
2697 "{}",2710 "{}",
2698 .{status},2711 .{diag},
2699 );2712 );
2700 }2713 }
27012714
2702 // Invalid int literal2715 // Invalid int literal
2703 {2716 {
2704 var status: Status = .{};2717 var diag: Diagnostics = .{};
2705 defer status.deinit(gpa);2718 defer diag.deinit(gpa);
2706 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &status, .{}));2719 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &diag, .{}));
2707 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{status});2720 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{}", .{diag});
2708 }2721 }
27092722
2710 // Notes on invalid int literal2723 // Notes on invalid int literal
2711 {2724 {
2712 var status: Status = .{};2725 var diag: Diagnostics = .{};
2713 defer status.deinit(gpa);2726 defer diag.deinit(gpa);
2714 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &status, .{}));2727 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &diag, .{}));
2715 try std.testing.expectFmt(2728 try std.testing.expectFmt(
2716 \\1:1: error: number '0123' has leading zero2729 \\1:1: error: number '0123' has leading zero
2717 \\1:1: note: use '0o' prefix for octal literals2730 \\1:1: note: use '0o' prefix for octal literals
2718 \\2731 \\
2719 , "{}", .{status});2732 , "{}", .{diag});
2720 }2733 }
2721}2734}
27222735
...@@ -2724,23 +2737,23 @@ test "std.zon negative char" {...@@ -2724,23 +2737,23 @@ test "std.zon negative char" {
2724 const gpa = std.testing.allocator;2737 const gpa = std.testing.allocator;
27252738
2726 {2739 {
2727 var status: Status = .{};2740 var diag: Diagnostics = .{};
2728 defer status.deinit(gpa);2741 defer diag.deinit(gpa);
2729 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &status, .{}));2742 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &diag, .{}));
2730 try std.testing.expectFmt(2743 try std.testing.expectFmt(
2731 "1:1: error: expected number or 'inf' after '-'\n",2744 "1:1: error: expected number or 'inf' after '-'\n",
2732 "{}",2745 "{}",
2733 .{status},2746 .{diag},
2734 );2747 );
2735 }2748 }
2736 {2749 {
2737 var status: Status = .{};2750 var diag: Diagnostics = .{};
2738 defer status.deinit(gpa);2751 defer diag.deinit(gpa);
2739 try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &status, .{}));2752 try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &diag, .{}));
2740 try std.testing.expectFmt(2753 try std.testing.expectFmt(
2741 "1:1: error: expected number or 'inf' after '-'\n",2754 "1:1: error: expected number or 'inf' after '-'\n",
2742 "{}",2755 "{}",
2743 .{status},2756 .{diag},
2744 );2757 );
2745 }2758 }
2746}2759}
...@@ -2821,81 +2834,81 @@ test "std.zon parse float" {...@@ -2821,81 +2834,81 @@ test "std.zon parse float" {
28212834
2822 // Negative nan not allowed2835 // Negative nan not allowed
2823 {2836 {
2824 var status: Status = .{};2837 var diag: Diagnostics = .{};
2825 defer status.deinit(gpa);2838 defer diag.deinit(gpa);
2826 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &status, .{}));2839 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &diag, .{}));
2827 try std.testing.expectFmt(2840 try std.testing.expectFmt(
2828 "1:1: error: expected number or 'inf' after '-'\n",2841 "1:1: error: expected number or 'inf' after '-'\n",
2829 "{}",2842 "{}",
2830 .{status},2843 .{diag},
2831 );2844 );
2832 }2845 }
28332846
2834 // nan as int not allowed2847 // nan as int not allowed
2835 {2848 {
2836 var status: Status = .{};2849 var diag: Diagnostics = .{};
2837 defer status.deinit(gpa);2850 defer diag.deinit(gpa);
2838 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{}));2851 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));
2839 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});2852 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
2840 }2853 }
28412854
2842 // nan as int not allowed2855 // nan as int not allowed
2843 {2856 {
2844 var status: Status = .{};2857 var diag: Diagnostics = .{};
2845 defer status.deinit(gpa);2858 defer diag.deinit(gpa);
2846 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &status, .{}));2859 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));
2847 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});2860 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
2848 }2861 }
28492862
2850 // inf as int not allowed2863 // inf as int not allowed
2851 {2864 {
2852 var status: Status = .{};2865 var diag: Diagnostics = .{};
2853 defer status.deinit(gpa);2866 defer diag.deinit(gpa);
2854 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &status, .{}));2867 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &diag, .{}));
2855 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});2868 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
2856 }2869 }
28572870
2858 // -inf as int not allowed2871 // -inf as int not allowed
2859 {2872 {
2860 var status: Status = .{};2873 var diag: Diagnostics = .{};
2861 defer status.deinit(gpa);2874 defer diag.deinit(gpa);
2862 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &status, .{}));2875 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &diag, .{}));
2863 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{status});2876 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{}", .{diag});
2864 }2877 }
28652878
2866 // Bad identifier as float2879 // Bad identifier as float
2867 {2880 {
2868 var status: Status = .{};2881 var diag: Diagnostics = .{};
2869 defer status.deinit(gpa);2882 defer diag.deinit(gpa);
2870 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &status, .{}));2883 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &diag, .{}));
2871 try std.testing.expectFmt(2884 try std.testing.expectFmt(
2872 \\1:1: error: invalid expression2885 \\1:1: error: invalid expression
2873 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'2886 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
2874 \\1:1: note: precede identifier with '.' for an enum literal2887 \\1:1: note: precede identifier with '.' for an enum literal
2875 \\2888 \\
2876 , "{}", .{status});2889 , "{}", .{diag});
2877 }2890 }
28782891
2879 {2892 {
2880 var status: Status = .{};2893 var diag: Diagnostics = .{};
2881 defer status.deinit(gpa);2894 defer diag.deinit(gpa);
2882 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &status, .{}));2895 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &diag, .{}));
2883 try std.testing.expectFmt(2896 try std.testing.expectFmt(
2884 "1:1: error: expected number or 'inf' after '-'\n",2897 "1:1: error: expected number or 'inf' after '-'\n",
2885 "{}",2898 "{}",
2886 .{status},2899 .{diag},
2887 );2900 );
2888 }2901 }
28892902
2890 // Non float as float2903 // Non float as float
2891 {2904 {
2892 var status: Status = .{};2905 var diag: Diagnostics = .{};
2893 defer status.deinit(gpa);2906 defer diag.deinit(gpa);
2894 try std.testing.expectError(2907 try std.testing.expectError(
2895 error.ParseZon,2908 error.ParseZon,
2896 fromSlice(f32, gpa, "\"foo\"", &status, .{}),2909 fromSlice(f32, gpa, "\"foo\"", &diag, .{}),
2897 );2910 );
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});
2899 }2912 }
2900}2913}
29012914
...@@ -3132,69 +3145,69 @@ test "std.zon vector" {...@@ -3132,69 +3145,69 @@ test "std.zon vector" {
31323145
3133 // Too few fields3146 // Too few fields
3134 {3147 {
3135 var status: Status = .{};3148 var diag: Diagnostics = .{};
3136 defer status.deinit(gpa);3149 defer diag.deinit(gpa);
3137 try std.testing.expectError(3150 try std.testing.expectError(
3138 error.ParseZon,3151 error.ParseZon,
3139 fromSlice(@Vector(2, f32), gpa, ".{0.5}", &status, .{}),3152 fromSlice(@Vector(2, f32), gpa, ".{0.5}", &diag, .{}),
3140 );3153 );
3141 try std.testing.expectFmt(3154 try std.testing.expectFmt(
3142 "1:2: error: expected 2 vector elements; found 1\n",3155 "1:2: error: expected 2 vector elements; found 1\n",
3143 "{}",3156 "{}",
3144 .{status},3157 .{diag},
3145 );3158 );
3146 }3159 }
31473160
3148 // Too many fields3161 // Too many fields
3149 {3162 {
3150 var status: Status = .{};3163 var diag: Diagnostics = .{};
3151 defer status.deinit(gpa);3164 defer diag.deinit(gpa);
3152 try std.testing.expectError(3165 try std.testing.expectError(
3153 error.ParseZon,3166 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, .{}),
3155 );3168 );
3156 try std.testing.expectFmt(3169 try std.testing.expectFmt(
3157 "1:2: error: expected 2 vector elements; found 3\n",3170 "1:2: error: expected 2 vector elements; found 3\n",
3158 "{}",3171 "{}",
3159 .{status},3172 .{diag},
3160 );3173 );
3161 }3174 }
31623175
3163 // Wrong type fields3176 // Wrong type fields
3164 {3177 {
3165 var status: Status = .{};3178 var diag: Diagnostics = .{};
3166 defer status.deinit(gpa);3179 defer diag.deinit(gpa);
3167 try std.testing.expectError(3180 try std.testing.expectError(
3168 error.ParseZon,3181 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, .{}),
3170 );3183 );
3171 try std.testing.expectFmt(3184 try std.testing.expectFmt(
3172 "1:8: error: expected type 'f32'\n",3185 "1:8: error: expected type 'f32'\n",
3173 "{}",3186 "{}",
3174 .{status},3187 .{diag},
3175 );3188 );
3176 }3189 }
31773190
3178 // Wrong type3191 // Wrong type
3179 {3192 {
3180 var status: Status = .{};3193 var diag: Diagnostics = .{};
3181 defer status.deinit(gpa);3194 defer diag.deinit(gpa);
3182 try std.testing.expectError(3195 try std.testing.expectError(
3183 error.ParseZon,3196 error.ParseZon,
3184 fromSlice(@Vector(3, u8), gpa, "true", &status, .{}),3197 fromSlice(@Vector(3, u8), gpa, "true", &diag, .{}),
3185 );3198 );
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});
3187 }3200 }
31883201
3189 // Elements should get freed on error3202 // Elements should get freed on error
3190 {3203 {
3191 var status: Status = .{};3204 var diag: Diagnostics = .{};
3192 defer status.deinit(gpa);3205 defer diag.deinit(gpa);
3193 try std.testing.expectError(3206 try std.testing.expectError(
3194 error.ParseZon,3207 error.ParseZon,
3195 fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &status, .{}),3208 fromSlice(@Vector(3, *u8), gpa, ".{1, true, 3}", &diag, .{}),
3196 );3209 );
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});
3198 }3211 }
3199}3212}
32003213
...@@ -3312,132 +3325,156 @@ test "std.zon add pointers" {...@@ -3312,132 +3325,156 @@ test "std.zon add pointers" {
33123325
3313 // Test that optional types are flattened correctly in errors3326 // Test that optional types are flattened correctly in errors
3314 {3327 {
3315 var status: Status = .{};3328 var diag: Diagnostics = .{};
3316 defer status.deinit(gpa);3329 defer diag.deinit(gpa);
3317 try std.testing.expectError(3330 try std.testing.expectError(
3318 error.ParseZon,3331 error.ParseZon,
3319 fromSlice(*const ?*const u8, gpa, "true", &status, .{}),3332 fromSlice(*const ?*const u8, gpa, "true", &diag, .{}),
3320 );3333 );
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});
3322 }3335 }
33233336
3324 {3337 {
3325 var status: Status = .{};3338 var diag: Diagnostics = .{};
3326 defer status.deinit(gpa);3339 defer diag.deinit(gpa);
3327 try std.testing.expectError(3340 try std.testing.expectError(
3328 error.ParseZon,3341 error.ParseZon,
3329 fromSlice(*const ?*const f32, gpa, "true", &status, .{}),3342 fromSlice(*const ?*const f32, gpa, "true", &diag, .{}),
3330 );3343 );
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});
3332 }3345 }
33333346
3334 {3347 {
3335 var status: Status = .{};3348 var diag: Diagnostics = .{};
3336 defer status.deinit(gpa);3349 defer diag.deinit(gpa);
3337 try std.testing.expectError(3350 try std.testing.expectError(
3338 error.ParseZon,3351 error.ParseZon,
3339 fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &status, .{}),3352 fromSlice(*const ?*const @Vector(3, u8), gpa, "true", &diag, .{}),
3340 );3353 );
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});
3342 }3355 }
33433356
3344 {3357 {
3345 var status: Status = .{};3358 var diag: Diagnostics = .{};
3346 defer status.deinit(gpa);3359 defer diag.deinit(gpa);
3347 try std.testing.expectError(3360 try std.testing.expectError(
3348 error.ParseZon,3361 error.ParseZon,
3349 fromSlice(*const ?*const bool, gpa, "10", &status, .{}),3362 fromSlice(*const ?*const bool, gpa, "10", &diag, .{}),
3350 );3363 );
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});
3352 }3365 }
33533366
3354 {3367 {
3355 var status: Status = .{};3368 var diag: Diagnostics = .{};
3356 defer status.deinit(gpa);3369 defer diag.deinit(gpa);
3357 try std.testing.expectError(3370 try std.testing.expectError(
3358 error.ParseZon,3371 error.ParseZon,
3359 fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &status, .{}),3372 fromSlice(*const ?*const struct { a: i32 }, gpa, "true", &diag, .{}),
3360 );3373 );
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});
3362 }3375 }
33633376
3364 {3377 {
3365 var status: Status = .{};3378 var diag: Diagnostics = .{};
3366 defer status.deinit(gpa);3379 defer diag.deinit(gpa);
3367 try std.testing.expectError(3380 try std.testing.expectError(
3368 error.ParseZon,3381 error.ParseZon,
3369 fromSlice(*const ?*const struct { i32 }, gpa, "true", &status, .{}),3382 fromSlice(*const ?*const struct { i32 }, gpa, "true", &diag, .{}),
3370 );3383 );
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});
3372 }3385 }
33733386
3374 {3387 {
3375 var status: Status = .{};3388 var diag: Diagnostics = .{};
3376 defer status.deinit(gpa);3389 defer diag.deinit(gpa);
3377 try std.testing.expectError(3390 try std.testing.expectError(
3378 error.ParseZon,3391 error.ParseZon,
3379 fromSlice(*const ?*const union { x: void }, gpa, "true", &status, .{}),3392 fromSlice(*const ?*const union { x: void }, gpa, "true", &diag, .{}),
3380 );3393 );
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});
3382 }3395 }
33833396
3384 {3397 {
3385 var status: Status = .{};3398 var diag: Diagnostics = .{};
3386 defer status.deinit(gpa);3399 defer diag.deinit(gpa);
3387 try std.testing.expectError(3400 try std.testing.expectError(
3388 error.ParseZon,3401 error.ParseZon,
3389 fromSlice(*const ?*const [3]u8, gpa, "true", &status, .{}),3402 fromSlice(*const ?*const [3]u8, gpa, "true", &diag, .{}),
3390 );3403 );
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});
3392 }3405 }
33933406
3394 {3407 {
3395 var status: Status = .{};3408 var diag: Diagnostics = .{};
3396 defer status.deinit(gpa);3409 defer diag.deinit(gpa);
3397 try std.testing.expectError(3410 try std.testing.expectError(
3398 error.ParseZon,3411 error.ParseZon,
3399 fromSlice(?[3]u8, gpa, "true", &status, .{}),3412 fromSlice(?[3]u8, gpa, "true", &diag, .{}),
3400 );3413 );
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});
3402 }3415 }
34033416
3404 {3417 {
3405 var status: Status = .{};3418 var diag: Diagnostics = .{};
3406 defer status.deinit(gpa);3419 defer diag.deinit(gpa);
3407 try std.testing.expectError(3420 try std.testing.expectError(
3408 error.ParseZon,3421 error.ParseZon,
3409 fromSlice(*const ?*const []u8, gpa, "true", &status, .{}),3422 fromSlice(*const ?*const []u8, gpa, "true", &diag, .{}),
3410 );3423 );
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});
3412 }3425 }
34133426
3414 {3427 {
3415 var status: Status = .{};3428 var diag: Diagnostics = .{};
3416 defer status.deinit(gpa);3429 defer diag.deinit(gpa);
3417 try std.testing.expectError(3430 try std.testing.expectError(
3418 error.ParseZon,3431 error.ParseZon,
3419 fromSlice(?[]u8, gpa, "true", &status, .{}),3432 fromSlice(?[]u8, gpa, "true", &diag, .{}),
3420 );3433 );
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});
3422 }3435 }
34233436
3424 {3437 {
3425 var status: Status = .{};3438 var diag: Diagnostics = .{};
3426 defer status.deinit(gpa);3439 defer diag.deinit(gpa);
3427 try std.testing.expectError(3440 try std.testing.expectError(
3428 error.ParseZon,3441 error.ParseZon,
3429 fromSlice(*const ?*const []const u8, gpa, "true", &status, .{}),3442 fromSlice(*const ?*const []const u8, gpa, "true", &diag, .{}),
3430 );3443 );
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});
3432 }3445 }
34333446
3434 {3447 {
3435 var status: Status = .{};3448 var diag: Diagnostics = .{};
3436 defer status.deinit(gpa);3449 defer diag.deinit(gpa);
3437 try std.testing.expectError(3450 try std.testing.expectError(
3438 error.ParseZon,3451 error.ParseZon,
3439 fromSlice(*const ?*const enum { foo }, gpa, "true", &status, .{}),3452 fromSlice(*const ?*const enum { foo }, gpa, "true", &diag, .{}),
3440 );3453 );
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));
3442 }3479 }
3443}3480}