authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-08-07 15:01:20-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
loge4a7988fec0d53e5f48a1701aeebacf192198203
treef8f440343b8841c3c3d3a5c81c6c9e8cfc669e14
parentab52406e0c5598b651b11f3f7f93ad5ddb875896

Add a path to Errors formatter, add `log` and `fatal` helpers


1 files changed, 440 insertions(+), 277 deletions(-)

lib/std/zon/parse.zig+440-277
......@@ -7,6 +7,7 @@
77//! parsing, see `std.zig.ZonGen`. For importing ZON at compile time, use `@import`.
88
99const std = @import("std");
10const builtin = @import("builtin");
1011const Allocator = std.mem.Allocator;
1112const Ast = std.zig.Ast;
1213const Zoir = std.zig.Zoir;
......@@ -39,7 +40,7 @@ pub const Error = struct {
3940 notes: []Note,
4041 };
4142
42 fn init(ast: *const Ast, options: InitOptions) @This() {
43 fn init(ast: *const Ast, options: InitOptions) Error {
4344 return .{
4445 .msg = options.msg,
4546 .loc = astLoc(ast, options.token, options.node_or_offset),
......@@ -90,40 +91,110 @@ pub const Error = struct {
9091 };
9192};
9293
93/// Errors encountered while parsing ZON. Consider logging this using the default format method to
94/// provide users with feedback on the failure.
94/// Errors encountered while parsing ZON. See `log` and `fatal` for reporting errors to the user.
9595pub const Errors = struct {
9696 arena: Allocator,
9797 list: std.ArrayList(Error),
9898
99 pub fn init(arena: Allocator) @This() {
99 pub fn init(arena: Allocator) Errors {
100100 return .{
101101 .arena = arena,
102102 .list = .empty,
103103 };
104104 }
105105
106 pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void {
107 for (self.list.items) |e| {
108 try w.print("{d}:{d}: error: {s}\n", .{
109 e.loc.line + 1,
110 e.loc.column + 1,
111 e.msg,
112 });
106 /// Log the failure with `std.log.err`.
107 pub fn log(
108 self: *const Errors,
109 path: []const u8,
110 err: error{ OutOfMemory, ParseZon },
111 ) void {
112 std.log.err("{s}: {}\n{f}", .{ path, err, self.fmt(path) });
113 }
113114
114 for (e.notes) |note| {
115 try w.print("{d}:{d}: note: {s}\n", .{
116 note.loc.line + 1,
117 note.loc.column + 1,
118 note.msg,
119 });
120 }
121 }
115 test log {
116 const gpa = std.testing.allocator;
117 var arena_allocator: ArenaAllocator = .init(gpa);
118 defer arena_allocator.deinit();
119 const arena = arena_allocator.allocator();
120
121 const MyType = struct {
122 foo: u32,
123 bar: u32,
124 };
125
126 const errors: Errors = .init(arena);
127 const parsed: MyType = fromSlice(MyType, .{
128 .gpa = gpa,
129 .source = ".{ .foo = 1, .bar = 2 }",
130 .errors = null,
131 }) catch |err| b: {
132 errors.log("input.zon", err);
133 break :b .{ .foo = 0, .bar = 0 };
134 };
135 _ = parsed;
136 }
137
138 /// Log the failure with `std.log.err`, and then terminate the process with exit code 1.
139 pub fn fatal(
140 self: *const Errors,
141 path: []const u8,
142 err: error{ OutOfMemory, ParseZon },
143 ) noreturn {
144 std.process.fatal("{s}: {}\n{f}", .{ path, err, self.fmt(path) });
145 }
146
147 test fatal {
148 const gpa = std.testing.allocator;
149 var arena_allocator: ArenaAllocator = .init(gpa);
150 defer arena_allocator.deinit();
151 const arena = arena_allocator.allocator();
152
153 const MyType = struct {
154 foo: u32,
155 bar: u32,
156 };
157
158 const errors: Errors = .init(arena);
159 const parsed = fromSlice(MyType, .{
160 .gpa = gpa,
161 .source = ".{ .foo = 1, .bar = 2 }",
162 .errors = null,
163 }) catch |err| errors.fatal("input.zon", err);
164 _ = parsed;
122165 }
123166
124 pub fn clear(self: *@This()) void {
125 self.errors.clearRetainingCapacity();
167 pub fn fmt(self: *const Errors, path: []const u8) Formatter {
168 return .{
169 .path = path,
170 .errors = self.list.items,
171 };
126172 }
173
174 pub const Formatter = struct {
175 path: []const u8,
176 errors: []const Error,
177
178 pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void {
179 for (self.errors) |e| {
180 try w.print("{s}:", .{self.path});
181 try w.print("{d}:{d}: error: {s}\n", .{
182 e.loc.line + 1,
183 e.loc.column + 1,
184 e.msg,
185 });
186
187 for (e.notes) |note| {
188 try w.print("{s}:", .{self.path});
189 try w.print("{d}:{d}: note: {s}\n", .{
190 note.loc.line + 1,
191 note.loc.column + 1,
192 note.msg,
193 });
194 }
195 }
196 }
197 };
127198};
128199
129200pub const FromSliceOptions = struct {
......@@ -432,7 +503,7 @@ const Parser = struct {
432503 const ParseExprError = error{ ParseZon, OutOfMemory };
433504
434505 fn parseExprInto(
435 self: *@This(),
506 self: *Parser,
436507 node: Zoir.Node.Index,
437508 out: anytype,
438509 initialized: bool,
......@@ -519,7 +590,7 @@ const Parser = struct {
519590 /// example, `**?**u8` becomes `?u8`, and types that involve user specified type names are just
520591 /// referred to by the type of container.
521592 fn failExpectedType(
522 self: @This(),
593 self: Parser,
523594 T: type,
524595 node: Zoir.Node.Index,
525596 ) error{ ParseZon, OutOfMemory } {
......@@ -528,7 +599,7 @@ const Parser = struct {
528599 }
529600
530601 fn failExpectedTypeInner(
531 self: @This(),
602 self: Parser,
532603 T: type,
533604 opt: bool,
534605 node: Zoir.Node.Index,
......@@ -598,7 +669,7 @@ const Parser = struct {
598669 }
599670 }
600671
601 fn parseBool(self: @This(), node: Zoir.Node.Index) !bool {
672 fn parseBool(self: Parser, node: Zoir.Node.Index) !bool {
602673 switch (node.get(self.zoir)) {
603674 .true => return true,
604675 .false => return false,
......@@ -606,7 +677,7 @@ const Parser = struct {
606677 }
607678 }
608679
609 fn parseInt(self: @This(), T: type, node: Zoir.Node.Index) !T {
680 fn parseInt(self: Parser, T: type, node: Zoir.Node.Index) !T {
610681 switch (node.get(self.zoir)) {
611682 .int_literal => |int| switch (int) {
612683 .small => |val| return std.math.cast(T, val) orelse
......@@ -623,7 +694,7 @@ const Parser = struct {
623694 }
624695 }
625696
626 fn parseFloat(self: @This(), T: type, node: Zoir.Node.Index) !T {
697 fn parseFloat(self: Parser, T: type, node: Zoir.Node.Index) !T {
627698 switch (node.get(self.zoir)) {
628699 .int_literal => |int| switch (int) {
629700 .small => |val| return @floatFromInt(val),
......@@ -638,7 +709,7 @@ const Parser = struct {
638709 }
639710 }
640711
641 fn parseEnumLiteral(self: @This(), T: type, node: Zoir.Node.Index) !T {
712 fn parseEnumLiteral(self: Parser, T: type, node: Zoir.Node.Index) !T {
642713 switch (node.get(self.zoir)) {
643714 .enum_literal => |field_name| {
644715 // Create a comptime string map for the enum fields
......@@ -658,7 +729,7 @@ const Parser = struct {
658729 }
659730 }
660731
661 fn parseSlicePointer(self: *@This(), T: type, node: Zoir.Node.Index) ParseExprInnerError!T {
732 fn parseSlicePointer(self: *Parser, T: type, node: Zoir.Node.Index) ParseExprInnerError!T {
662733 switch (node.get(self.zoir)) {
663734 .string_literal => return self.parseString(T, node),
664735 .array_literal => |nodes| return self.parseSlice(T, nodes),
......@@ -667,7 +738,7 @@ const Parser = struct {
667738 }
668739 }
669740
670 fn parseString(self: *@This(), T: type, node: Zoir.Node.Index) ParseExprInnerError!T {
741 fn parseString(self: *Parser, T: type, node: Zoir.Node.Index) ParseExprInnerError!T {
671742 const ast_node = node.getAstNode(self.zoir);
672743 const pointer = @typeInfo(T).pointer;
673744 var size_hint = ZonGen.strLitSizeHint(self.ast, ast_node);
......@@ -702,7 +773,7 @@ const Parser = struct {
702773 }
703774 }
704775
705 fn parseSlice(self: *@This(), T: type, nodes: Zoir.Node.Index.Range) !T {
776 fn parseSlice(self: *Parser, T: type, nodes: Zoir.Node.Index.Range) !T {
706777 const pointer = @typeInfo(T).pointer;
707778
708779 // Make sure we're working with a slice
......@@ -727,7 +798,7 @@ const Parser = struct {
727798 return slice;
728799 }
729800
730 fn parseArrayInto(self: *@This(), node: Zoir.Node.Index, out: anytype) !void {
801 fn parseArrayInto(self: *Parser, node: Zoir.Node.Index, out: anytype) !void {
731802 const nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir)) {
732803 .array_literal => |nodes| nodes,
733804 .empty_literal => .{ .start = node, .len = 0 },
......@@ -761,7 +832,7 @@ const Parser = struct {
761832 }
762833 }
763834
764 fn parseVectorInto(self: *@This(), node: Zoir.Node.Index, out: anytype) !void {
835 fn parseVectorInto(self: *Parser, node: Zoir.Node.Index, out: anytype) !void {
765836 const vector = @typeInfo(@TypeOf(out.*)).vector;
766837 var array: [vector.len]vector.child = undefined;
767838 try self.parseArrayInto(node, &array);
......@@ -769,7 +840,7 @@ const Parser = struct {
769840 }
770841
771842 fn parseStructInto(
772 self: *@This(),
843 self: *Parser,
773844 node: Zoir.Node.Index,
774845 out: anytype,
775846 initialized: bool,
......@@ -843,7 +914,7 @@ const Parser = struct {
843914 }
844915 }
845916
846 fn parseTupleInto(self: *@This(), node: Zoir.Node.Index, out: anytype) !void {
917 fn parseTupleInto(self: *Parser, node: Zoir.Node.Index, out: anytype) !void {
847918 const nodes: Zoir.Node.Index.Range = switch (node.get(self.zoir)) {
848919 .array_literal => |nodes| nodes,
849920 .empty_literal => .{ .start = node, .len = 0 },
......@@ -879,7 +950,7 @@ const Parser = struct {
879950 }
880951
881952 fn parseUnionInto(
882 self: *@This(),
953 self: *Parser,
883954 node: Zoir.Node.Index,
884955 out: anytype,
885956 initialized: bool,
......@@ -981,7 +1052,7 @@ const Parser = struct {
9811052 }
9821053
9831054 fn failTokenFmt(
984 self: @This(),
1055 self: Parser,
9851056 token: Ast.TokenIndex,
9861057 offset: u32,
9871058 comptime fmt: []const u8,
......@@ -992,7 +1063,7 @@ const Parser = struct {
9921063 }
9931064
9941065 fn failTokenFmtNote(
995 self: @This(),
1066 self: Parser,
9961067 token: Ast.TokenIndex,
9971068 offset: u32,
9981069 comptime fmt: []const u8,
......@@ -1011,7 +1082,7 @@ const Parser = struct {
10111082 }
10121083
10131084 fn failNodeFmt(
1014 self: @This(),
1085 self: Parser,
10151086 node: Zoir.Node.Index,
10161087 comptime fmt: []const u8,
10171088 args: anytype,
......@@ -1022,7 +1093,7 @@ const Parser = struct {
10221093 }
10231094
10241095 fn failToken(
1025 self: @This(),
1096 self: Parser,
10261097 failure: Error,
10271098 ) error{ OutOfMemory, ParseZon } {
10281099 @branchHint(.cold);
......@@ -1031,7 +1102,7 @@ const Parser = struct {
10311102 }
10321103
10331104 fn failNode(
1034 self: @This(),
1105 self: Parser,
10351106 node: Zoir.Node.Index,
10361107 msg: []const u8,
10371108 ) error{ OutOfMemory, ParseZon } {
......@@ -1046,7 +1117,7 @@ const Parser = struct {
10461117 }
10471118
10481119 fn failCannotRepresent(
1049 self: @This(),
1120 self: Parser,
10501121 T: type,
10511122 node: Zoir.Node.Index,
10521123 ) error{ OutOfMemory, ParseZon } {
......@@ -1055,7 +1126,7 @@ const Parser = struct {
10551126 }
10561127
10571128 fn failUnexpected(
1058 self: @This(),
1129 self: Parser,
10591130 T: type,
10601131 item_kind: []const u8,
10611132 node: Zoir.Node.Index,
......@@ -1111,7 +1182,7 @@ const Parser = struct {
11111182 // the value matched, but doing so doesn't seem to support any real use cases
11121183 // so isn't worth the complexity at the moment.
11131184 fn failComptimeField(
1114 self: @This(),
1185 self: Parser,
11151186 node: Zoir.Node.Index,
11161187 field: usize,
11171188 ) error{ OutOfMemory, ParseZon } {
......@@ -1306,7 +1377,10 @@ test "std.zon ast errors" {
13061377 .errors = &errors,
13071378 }),
13081379 );
1309 try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{f}", .{errors});
1380 try std.testing.expectFmt(
1381 \\input.zon:1:13: error: expected ',' after initializer
1382 \\
1383 , "{f}", .{errors.fmt("input.zon")});
13101384}
13111385
13121386test "std.zon comments" {
......@@ -1336,11 +1410,7 @@ test "std.zon comments" {
13361410 ,
13371411 .errors = &errors,
13381412 }));
1339 try std.testing.expectFmt(
1340 "1:1: error: expected expression, found 'a document comment'\n",
1341 "{f}",
1342 .{errors},
1343 );
1413 try std.testing.expectFmt("input.zon:1:1: error: expected expression, found 'a document comment'\n", "{f}", .{errors.fmt("input.zon")});
13441414 }
13451415}
13461416
......@@ -1356,7 +1426,9 @@ test "std.zon failure/oom formatting" {
13561426 .source = "\"foo\"",
13571427 .errors = &errors,
13581428 }));
1359 try std.testing.expectFmt("", "{f}", .{errors});
1429 try std.testing.expectFmt(
1430 \\
1431 , "{f}", .{errors.fmt("input.zon")});
13601432}
13611433
13621434test "std.zon fromSliceAlloc syntax error" {
......@@ -1497,13 +1569,10 @@ test "std.zon unions" {
14971569 }),
14981570 );
14991571 try std.testing.expectFmt(
1500 \\1:4: error: unexpected field 'z'
1501 \\1:4: note: supported: 'x', 'y'
1572 \\input.zon:1:4: error: unexpected field 'z'
1573 \\input.zon:1:4: note: supported: 'x', 'y'
15021574 \\
1503 ,
1504 "{f}",
1505 .{errors},
1506 );
1575 , "{f}", .{errors.fmt("input.zon")});
15071576 }
15081577
15091578 // Explicit void field
......@@ -1519,7 +1588,10 @@ test "std.zon unions" {
15191588 .errors = &errors,
15201589 }),
15211590 );
1522 try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{f}", .{errors});
1591 try std.testing.expectFmt(
1592 \\input.zon:1:6: error: expected type 'void'
1593 \\
1594 , "{f}", .{errors.fmt("input.zon")});
15231595 }
15241596
15251597 // Extra field
......@@ -1535,7 +1607,10 @@ test "std.zon unions" {
15351607 .errors = &errors,
15361608 }),
15371609 );
1538 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{errors});
1610 try std.testing.expectFmt(
1611 \\input.zon:1:2: error: expected union
1612 \\
1613 , "{f}", .{errors.fmt("input.zon")});
15391614 }
15401615
15411616 // No fields
......@@ -1551,7 +1626,10 @@ test "std.zon unions" {
15511626 .errors = &errors,
15521627 }),
15531628 );
1554 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{errors});
1629 try std.testing.expectFmt(
1630 \\input.zon:1:2: error: expected union
1631 \\
1632 , "{f}", .{errors.fmt("input.zon")});
15551633 }
15561634
15571635 // Enum literals cannot coerce into untagged unions
......@@ -1564,7 +1642,10 @@ test "std.zon unions" {
15641642 .source = ".x",
15651643 .errors = &errors,
15661644 }));
1567 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{errors});
1645 try std.testing.expectFmt(
1646 \\input.zon:1:2: error: expected union
1647 \\
1648 , "{f}", .{errors.fmt("input.zon")});
15681649 }
15691650
15701651 // Unknown field for enum literal coercion
......@@ -1578,13 +1659,10 @@ test "std.zon unions" {
15781659 .errors = &errors,
15791660 }));
15801661 try std.testing.expectFmt(
1581 \\1:2: error: unexpected field 'y'
1582 \\1:2: note: supported: 'x'
1662 \\input.zon:1:2: error: unexpected field 'y'
1663 \\input.zon:1:2: note: supported: 'x'
15831664 \\
1584 ,
1585 "{f}",
1586 .{errors},
1587 );
1665 , "{f}", .{errors.fmt("input.zon")});
15881666 }
15891667
15901668 // Non void field for enum literal coercion
......@@ -1597,7 +1675,10 @@ test "std.zon unions" {
15971675 .source = ".x",
15981676 .errors = &errors,
15991677 }));
1600 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{errors});
1678 try std.testing.expectFmt(
1679 \\input.zon:1:2: error: expected union
1680 \\
1681 , "{f}", .{errors.fmt("input.zon")});
16011682 }
16021683}
16031684
......@@ -1669,13 +1750,10 @@ test "std.zon structs" {
16691750 }),
16701751 );
16711752 try std.testing.expectFmt(
1672 \\1:12: error: unexpected field 'z'
1673 \\1:12: note: supported: 'x', 'y'
1753 \\input.zon:1:12: error: unexpected field 'z'
1754 \\input.zon:1:12: note: supported: 'x', 'y'
16741755 \\
1675 ,
1676 "{f}",
1677 .{errors},
1678 );
1756 , "{f}", .{errors.fmt("input.zon")});
16791757 }
16801758
16811759 // Duplicate field
......@@ -1691,10 +1769,10 @@ test "std.zon structs" {
16911769 }),
16921770 );
16931771 try std.testing.expectFmt(
1694 \\1:4: error: duplicate struct field name
1695 \\1:12: note: duplicate name here
1772 \\input.zon:1:4: error: duplicate struct field name
1773 \\input.zon:1:12: note: duplicate name here
16961774 \\
1697 , "{f}", .{errors});
1775 , "{f}", .{errors.fmt("input.zon")});
16981776 }
16991777
17001778 // Ignore unknown fields
......@@ -1722,10 +1800,10 @@ test "std.zon structs" {
17221800 }),
17231801 );
17241802 try std.testing.expectFmt(
1725 \\1:4: error: unexpected field 'x'
1726 \\1:4: note: none expected
1803 \\input.zon:1:4: error: unexpected field 'x'
1804 \\input.zon:1:4: note: none expected
17271805 \\
1728 , "{f}", .{errors});
1806 , "{f}", .{errors.fmt("input.zon")});
17291807 }
17301808
17311809 // Missing field
......@@ -1740,7 +1818,10 @@ test "std.zon structs" {
17401818 .errors = &errors,
17411819 }),
17421820 );
1743 try std.testing.expectFmt("1:2: error: missing required field y\n", "{f}", .{errors});
1821 try std.testing.expectFmt(
1822 \\input.zon:1:2: error: missing required field y
1823 \\
1824 , "{f}", .{errors.fmt("input.zon")});
17441825 }
17451826
17461827 // Default field
......@@ -1776,9 +1857,9 @@ test "std.zon structs" {
17761857 });
17771858 try std.testing.expectError(error.ParseZon, parsed);
17781859 try std.testing.expectFmt(
1779 \\1:18: error: cannot initialize comptime field
1860 \\input.zon:1:18: error: cannot initialize comptime field
17801861 \\
1781 , "{f}", .{errors});
1862 , "{f}", .{errors.fmt("input.zon")});
17821863 }
17831864
17841865 // Enum field (regression test, we were previously getting the field name in an
......@@ -1816,10 +1897,10 @@ test "std.zon structs" {
18161897 });
18171898 try std.testing.expectError(error.ParseZon, parsed);
18181899 try std.testing.expectFmt(
1819 \\1:1: error: types are not available in ZON
1820 \\1:1: note: replace the type with '.'
1900 \\input.zon:1:1: error: types are not available in ZON
1901 \\input.zon:1:1: note: replace the type with '.'
18211902 \\
1822 , "{f}", .{errors});
1903 , "{f}", .{errors.fmt("input.zon")});
18231904 }
18241905
18251906 // Arrays
......@@ -1832,10 +1913,10 @@ test "std.zon structs" {
18321913 });
18331914 try std.testing.expectError(error.ParseZon, parsed);
18341915 try std.testing.expectFmt(
1835 \\1:1: error: types are not available in ZON
1836 \\1:1: note: replace the type with '.'
1916 \\input.zon:1:1: error: types are not available in ZON
1917 \\input.zon:1:1: note: replace the type with '.'
18371918 \\
1838 , "{f}", .{errors});
1919 , "{f}", .{errors.fmt("input.zon")});
18391920 }
18401921
18411922 // Slices
......@@ -1849,10 +1930,10 @@ test "std.zon structs" {
18491930 });
18501931 try std.testing.expectError(error.ParseZon, parsed);
18511932 try std.testing.expectFmt(
1852 \\1:1: error: types are not available in ZON
1853 \\1:1: note: replace the type with '.'
1933 \\input.zon:1:1: error: types are not available in ZON
1934 \\input.zon:1:1: note: replace the type with '.'
18541935 \\
1855 , "{f}", .{errors});
1936 , "{f}", .{errors.fmt("input.zon")});
18561937 }
18571938
18581939 // Tuples
......@@ -1865,10 +1946,10 @@ test "std.zon structs" {
18651946 });
18661947 try std.testing.expectError(error.ParseZon, parsed);
18671948 try std.testing.expectFmt(
1868 \\1:1: error: types are not available in ZON
1869 \\1:1: note: replace the type with '.'
1949 \\input.zon:1:1: error: types are not available in ZON
1950 \\input.zon:1:1: note: replace the type with '.'
18701951 \\
1871 , "{f}", .{errors});
1952 , "{f}", .{errors.fmt("input.zon")});
18721953 }
18731954
18741955 // Nested
......@@ -1881,10 +1962,10 @@ test "std.zon structs" {
18811962 });
18821963 try std.testing.expectError(error.ParseZon, parsed);
18831964 try std.testing.expectFmt(
1884 \\1:9: error: types are not available in ZON
1885 \\1:9: note: replace the type with '.'
1965 \\input.zon:1:9: error: types are not available in ZON
1966 \\input.zon:1:9: note: replace the type with '.'
18861967 \\
1887 , "{f}", .{errors});
1968 , "{f}", .{errors.fmt("input.zon")});
18881969 }
18891970 }
18901971}
......@@ -1955,7 +2036,10 @@ test "std.zon tuples" {
19552036 .errors = &errors,
19562037 }),
19572038 );
1958 try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{f}", .{errors});
2039 try std.testing.expectFmt(
2040 \\input.zon:1:14: error: index 2 outside of tuple length 2
2041 \\
2042 , "{f}", .{errors.fmt("input.zon")});
19592043 }
19602044
19612045 // Extra field
......@@ -1971,10 +2055,9 @@ test "std.zon tuples" {
19712055 }),
19722056 );
19732057 try std.testing.expectFmt(
1974 "1:2: error: missing tuple field with index 1\n",
1975 "{f}",
1976 .{errors},
1977 );
2058 \\input.zon:1:2: error: missing tuple field with index 1
2059 \\
2060 , "{f}", .{errors.fmt("input.zon")});
19782061 }
19792062
19802063 // Tuple with unexpected field names
......@@ -1989,7 +2072,7 @@ test "std.zon tuples" {
19892072 .errors = &errors,
19902073 }),
19912074 );
1992 try std.testing.expectFmt("1:2: error: expected tuple\n", "{f}", .{errors});
2075 try std.testing.expectFmt("input.zon:1:2: error: expected tuple\n", "{f}", .{errors.fmt("input.zon")});
19932076 }
19942077
19952078 // Struct with missing field names
......@@ -2004,7 +2087,10 @@ test "std.zon tuples" {
20042087 .errors = &errors,
20052088 }),
20062089 );
2007 try std.testing.expectFmt("1:2: error: expected struct\n", "{f}", .{errors});
2090 try std.testing.expectFmt(
2091 \\input.zon:1:2: error: expected struct
2092 \\
2093 , "{f}", .{errors.fmt("input.zon")});
20082094 }
20092095
20102096 // Comptime field
......@@ -2029,14 +2115,16 @@ test "std.zon tuples" {
20292115 });
20302116 try std.testing.expectError(error.ParseZon, parsed);
20312117 try std.testing.expectFmt(
2032 \\1:9: error: cannot initialize comptime field
2118 \\input.zon:1:9: error: cannot initialize comptime field
20332119 \\
2034 , "{f}", .{errors});
2120 , "{f}", .{errors.fmt("input.zon")});
20352121 }
20362122}
20372123
20382124// Test sizes 0 to 3 since small sizes get parsed differently
20392125test "std.zon arrays and slices" {
2126 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/20881
2127
20402128 const gpa = std.testing.allocator;
20412129 var arena_allocator: ArenaAllocator = .init(gpa);
20422130 defer arena_allocator.deinit();
......@@ -2210,10 +2298,9 @@ test "std.zon arrays and slices" {
22102298 }),
22112299 );
22122300 try std.testing.expectFmt(
2213 "1:3: error: index 0 outside of array of length 0\n",
2214 "{f}",
2215 .{errors},
2216 );
2301 \\input.zon:1:3: error: index 0 outside of array of length 0
2302 \\
2303 , "{f}", .{errors.fmt("input.zon")});
22172304 }
22182305
22192306 // Expect 1 find 2
......@@ -2228,10 +2315,9 @@ test "std.zon arrays and slices" {
22282315 }),
22292316 );
22302317 try std.testing.expectFmt(
2231 "1:8: error: index 1 outside of array of length 1\n",
2232 "{f}",
2233 .{errors},
2234 );
2318 \\input.zon:1:8: error: index 1 outside of array of length 1
2319 \\
2320 , "{f}", .{errors.fmt("input.zon")});
22352321 }
22362322
22372323 // Expect 2 find 1
......@@ -2246,10 +2332,9 @@ test "std.zon arrays and slices" {
22462332 }),
22472333 );
22482334 try std.testing.expectFmt(
2249 "1:2: error: expected 2 array elements; found 1\n",
2250 "{f}",
2251 .{errors},
2252 );
2335 \\input.zon:1:2: error: expected 2 array elements; found 1
2336 \\
2337 , "{f}", .{errors.fmt("input.zon")});
22532338 }
22542339
22552340 // Expect 3 find 0
......@@ -2263,11 +2348,7 @@ test "std.zon arrays and slices" {
22632348 .errors = &errors,
22642349 }),
22652350 );
2266 try std.testing.expectFmt(
2267 "1:2: error: expected 3 array elements; found 0\n",
2268 "{f}",
2269 .{errors},
2270 );
2351 try std.testing.expectFmt("input.zon:1:2: error: expected 3 array elements; found 0\n", "{f}", .{errors.fmt("input.zon")});
22712352 }
22722353
22732354 // Wrong inner type
......@@ -2283,7 +2364,10 @@ test "std.zon arrays and slices" {
22832364 .errors = &errors,
22842365 }),
22852366 );
2286 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{errors});
2367 try std.testing.expectFmt(
2368 \\input.zon:1:3: error: expected type 'bool'
2369 \\
2370 , "{f}", .{errors.fmt("input.zon")});
22872371 }
22882372
22892373 // Slice
......@@ -2298,7 +2382,7 @@ test "std.zon arrays and slices" {
22982382 .errors = &errors,
22992383 }),
23002384 );
2301 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{errors});
2385 try std.testing.expectFmt("input.zon:1:3: error: expected type 'bool'\n", "{f}", .{errors.fmt("input.zon")});
23022386 }
23032387 }
23042388
......@@ -2315,7 +2399,10 @@ test "std.zon arrays and slices" {
23152399 .errors = &errors,
23162400 }),
23172401 );
2318 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2402 try std.testing.expectFmt(
2403 \\input.zon:1:1: error: expected array
2404 \\
2405 , "{f}", .{errors.fmt("input.zon")});
23192406 }
23202407
23212408 // Slice
......@@ -2325,7 +2412,7 @@ test "std.zon arrays and slices" {
23252412 error.ParseZon,
23262413 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "'a'", .errors = &errors }),
23272414 );
2328 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2415 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
23292416 }
23302417 }
23312418
......@@ -2337,10 +2424,9 @@ test "std.zon arrays and slices" {
23372424 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = " &.{'a', 'b', 'c'}", .errors = &errors }),
23382425 );
23392426 try std.testing.expectFmt(
2340 "1:3: error: pointers are not available in ZON\n",
2341 "{f}",
2342 .{errors},
2343 );
2427 \\input.zon:1:3: error: pointers are not available in ZON
2428 \\
2429 , "{f}", .{errors.fmt("input.zon")});
23442430 }
23452431}
23462432
......@@ -2391,7 +2477,7 @@ test "std.zon string literal" {
23912477 error.ParseZon,
23922478 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "\"abcd\"", .errors = &errors }),
23932479 );
2394 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2480 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
23952481 }
23962482
23972483 {
......@@ -2400,7 +2486,10 @@ test "std.zon string literal" {
24002486 error.ParseZon,
24012487 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\abcd", .errors = &errors }),
24022488 );
2403 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2489 try std.testing.expectFmt(
2490 \\input.zon:1:1: error: expected array
2491 \\
2492 , "{f}", .{errors.fmt("input.zon")});
24042493 }
24052494 }
24062495
......@@ -2420,7 +2509,7 @@ test "std.zon string literal" {
24202509 .errors = &errors,
24212510 }),
24222511 );
2423 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2512 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
24242513 }
24252514
24262515 {
......@@ -2433,7 +2522,10 @@ test "std.zon string literal" {
24332522 .errors = &errors,
24342523 }),
24352524 );
2436 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2525 try std.testing.expectFmt(
2526 \\input.zon:1:1: error: expected array
2527 \\
2528 , "{f}", .{errors.fmt("input.zon")});
24372529 }
24382530 }
24392531
......@@ -2470,7 +2562,7 @@ test "std.zon string literal" {
24702562 error.ParseZon,
24712563 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\"foo\"", .errors = &errors }),
24722564 );
2473 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2565 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
24742566 }
24752567
24762568 {
......@@ -2479,7 +2571,10 @@ test "std.zon string literal" {
24792571 error.ParseZon,
24802572 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\foo", .errors = &errors }),
24812573 );
2482 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2574 try std.testing.expectFmt(
2575 \\input.zon:1:1: error: expected array
2576 \\
2577 , "{f}", .{errors.fmt("input.zon")});
24832578 }
24842579 }
24852580
......@@ -2490,7 +2585,10 @@ test "std.zon string literal" {
24902585 error.ParseZon,
24912586 fromSliceAlloc([]const u8, .{ .gpa = gpa, .arena = arena, .source = "true", .errors = &errors }),
24922587 );
2493 try std.testing.expectFmt("1:1: error: expected string\n", "{f}", .{errors});
2588 try std.testing.expectFmt(
2589 \\input.zon:1:1: error: expected string
2590 \\
2591 , "{f}", .{errors.fmt("input.zon")});
24942592 }
24952593
24962594 // Expecting string literal, getting an incompatible tuple
......@@ -2500,7 +2598,10 @@ test "std.zon string literal" {
25002598 error.ParseZon,
25012599 fromSliceAlloc([]const u8, .{ .gpa = gpa, .arena = arena, .source = ".{false}", .errors = &errors }),
25022600 );
2503 try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{f}", .{errors});
2601 try std.testing.expectFmt(
2602 \\input.zon:1:3: error: expected type 'u8'
2603 \\
2604 , "{f}", .{errors.fmt("input.zon")});
25042605 }
25052606
25062607 // Invalid string literal
......@@ -2510,7 +2611,10 @@ test "std.zon string literal" {
25102611 error.ParseZon,
25112612 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"\\a\"", .errors = &errors }),
25122613 );
2513 try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{f}", .{errors});
2614 try std.testing.expectFmt(
2615 \\input.zon:1:3: error: invalid escape character: 'a'
2616 \\
2617 , "{f}", .{errors.fmt("input.zon")});
25142618 }
25152619
25162620 // Slice wrong child type
......@@ -2521,7 +2625,10 @@ test "std.zon string literal" {
25212625 error.ParseZon,
25222626 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"a\"", .errors = &errors }),
25232627 );
2524 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2628 try std.testing.expectFmt(
2629 \\input.zon:1:1: error: expected array
2630 \\
2631 , "{f}", .{errors.fmt("input.zon")});
25252632 }
25262633
25272634 {
......@@ -2530,7 +2637,10 @@ test "std.zon string literal" {
25302637 error.ParseZon,
25312638 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\\\\a", .errors = &errors }),
25322639 );
2533 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2640 try std.testing.expectFmt(
2641 \\input.zon:1:1: error: expected array
2642 \\
2643 , "{f}", .{errors.fmt("input.zon")});
25342644 }
25352645 }
25362646
......@@ -2547,7 +2657,7 @@ test "std.zon string literal" {
25472657 .errors = &errors,
25482658 }),
25492659 );
2550 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2660 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
25512661 }
25522662
25532663 {
......@@ -2561,7 +2671,10 @@ test "std.zon string literal" {
25612671 .errors = &errors,
25622672 }),
25632673 );
2564 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{errors});
2674 try std.testing.expectFmt(
2675 \\input.zon:1:1: error: expected array
2676 \\
2677 , "{f}", .{errors.fmt("input.zon")});
25652678 }
25662679 }
25672680
......@@ -2657,13 +2770,10 @@ test "std.zon enum literals" {
26572770 }),
26582771 );
26592772 try std.testing.expectFmt(
2660 \\1:2: error: unexpected enum literal 'qux'
2661 \\1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
2773 \\input.zon:1:2: error: unexpected enum literal 'qux'
2774 \\input.zon:1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
26622775 \\
2663 ,
2664 "{f}",
2665 .{errors},
2666 );
2776 , "{f}", .{errors.fmt("input.zon")});
26672777 }
26682778
26692779 // Bad tag that's too long for parser
......@@ -2678,13 +2788,10 @@ test "std.zon enum literals" {
26782788 }),
26792789 );
26802790 try std.testing.expectFmt(
2681 \\1:2: error: unexpected enum literal 'foobarbaz'
2682 \\1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
2791 \\input.zon:1:2: error: unexpected enum literal 'foobarbaz'
2792 \\input.zon:1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
26832793 \\
2684 ,
2685 "{f}",
2686 .{errors},
2687 );
2794 , "{f}", .{errors.fmt("input.zon")});
26882795 }
26892796
26902797 // Bad type
......@@ -2698,7 +2805,10 @@ test "std.zon enum literals" {
26982805 .errors = &errors,
26992806 }),
27002807 );
2701 try std.testing.expectFmt("1:1: error: expected enum literal\n", "{f}", .{errors});
2808 try std.testing.expectFmt(
2809 \\input.zon:1:1: error: expected enum literal
2810 \\
2811 , "{f}", .{errors.fmt("input.zon")});
27022812 }
27032813
27042814 // Test embedded nulls in an identifier
......@@ -2713,10 +2823,9 @@ test "std.zon enum literals" {
27132823 }),
27142824 );
27152825 try std.testing.expectFmt(
2716 "1:2: error: identifier cannot contain null bytes\n",
2717 "{f}",
2718 .{errors},
2719 );
2826 \\input.zon:1:2: error: identifier cannot contain null bytes
2827 \\
2828 , "{f}", .{errors.fmt("input.zon")});
27202829 }
27212830}
27222831
......@@ -2750,11 +2859,11 @@ test "std.zon parse bool" {
27502859 }),
27512860 );
27522861 try std.testing.expectFmt(
2753 \\1:2: error: invalid expression
2754 \\1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
2755 \\1:2: note: precede identifier with '.' for an enum literal
2862 \\input.zon:1:2: error: invalid expression
2863 \\input.zon:1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
2864 \\input.zon:1:2: note: precede identifier with '.' for an enum literal
27562865 \\
2757 , "{f}", .{errors});
2866 , "{f}", .{errors.fmt("input.zon")});
27582867 }
27592868 {
27602869 var errors: Errors = .init(arena);
......@@ -2763,7 +2872,10 @@ test "std.zon parse bool" {
27632872 .source = "123",
27642873 .errors = &errors,
27652874 }));
2766 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{f}", .{errors});
2875 try std.testing.expectFmt(
2876 \\input.zon:1:1: error: expected type 'bool'
2877 \\
2878 , "{f}", .{errors.fmt("input.zon")});
27672879 }
27682880}
27692881
......@@ -2892,10 +3004,9 @@ test "std.zon parse int" {
28923004 .errors = &errors,
28933005 }));
28943006 try std.testing.expectFmt(
2895 "1:1: error: type 'i66' cannot represent value\n",
2896 "{f}",
2897 .{errors},
2898 );
3007 \\input.zon:1:1: error: type 'i66' cannot represent value
3008 \\
3009 , "{f}", .{errors.fmt("input.zon")});
28993010 }
29003011 {
29013012 var errors: Errors = .init(arena);
......@@ -2905,10 +3016,9 @@ test "std.zon parse int" {
29053016 .errors = &errors,
29063017 }));
29073018 try std.testing.expectFmt(
2908 "1:1: error: type 'i66' cannot represent value\n",
2909 "{f}",
2910 .{errors},
2911 );
3019 \\input.zon:1:1: error: type 'i66' cannot represent value
3020 \\
3021 , "{f}", .{errors.fmt("input.zon")});
29123022 }
29133023
29143024 // Test parsing whole number floats as integers
......@@ -3011,10 +3121,9 @@ test "std.zon parse int" {
30113121 .errors = &errors,
30123122 }));
30133123 try std.testing.expectFmt(
3014 "1:3: error: invalid digit 'a' for decimal base\n",
3015 "{f}",
3016 .{errors},
3017 );
3124 \\input.zon:1:3: error: invalid digit 'a' for decimal base
3125 \\
3126 , "{f}", .{errors.fmt("input.zon")});
30183127 }
30193128
30203129 // Failing to parse as int
......@@ -3025,7 +3134,10 @@ test "std.zon parse int" {
30253134 .source = "true",
30263135 .errors = &errors,
30273136 }));
3028 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{f}", .{errors});
3137 try std.testing.expectFmt(
3138 \\input.zon:1:1: error: expected type 'u8'
3139 \\
3140 , "{f}", .{errors.fmt("input.zon")});
30293141 }
30303142
30313143 // Failing because an int is out of range
......@@ -3037,10 +3149,9 @@ test "std.zon parse int" {
30373149 .errors = &errors,
30383150 }));
30393151 try std.testing.expectFmt(
3040 "1:1: error: type 'u8' cannot represent value\n",
3041 "{f}",
3042 .{errors},
3043 );
3152 \\input.zon:1:1: error: type 'u8' cannot represent value
3153 \\
3154 , "{f}", .{errors.fmt("input.zon")});
30443155 }
30453156
30463157 // Failing because a negative int is out of range
......@@ -3052,10 +3163,9 @@ test "std.zon parse int" {
30523163 .errors = &errors,
30533164 }));
30543165 try std.testing.expectFmt(
3055 "1:1: error: type 'i8' cannot represent value\n",
3056 "{f}",
3057 .{errors},
3058 );
3166 \\input.zon:1:1: error: type 'i8' cannot represent value
3167 \\
3168 , "{f}", .{errors.fmt("input.zon")});
30593169 }
30603170
30613171 // Failing because an unsigned int is negative
......@@ -3067,10 +3177,9 @@ test "std.zon parse int" {
30673177 .errors = &errors,
30683178 }));
30693179 try std.testing.expectFmt(
3070 "1:1: error: type 'u8' cannot represent value\n",
3071 "{f}",
3072 .{errors},
3073 );
3180 \\input.zon:1:1: error: type 'u8' cannot represent value
3181 \\
3182 , "{f}", .{errors.fmt("input.zon")});
30743183 }
30753184
30763185 // Failing because a float is non-whole
......@@ -3082,10 +3191,9 @@ test "std.zon parse int" {
30823191 .errors = &errors,
30833192 }));
30843193 try std.testing.expectFmt(
3085 "1:1: error: type 'u8' cannot represent value\n",
3086 "{f}",
3087 .{errors},
3088 );
3194 \\input.zon:1:1: error: type 'u8' cannot represent value
3195 \\
3196 , "{f}", .{errors.fmt("input.zon")});
30893197 }
30903198
30913199 // Failing because a float is negative
......@@ -3097,10 +3205,9 @@ test "std.zon parse int" {
30973205 .errors = &errors,
30983206 }));
30993207 try std.testing.expectFmt(
3100 "1:1: error: type 'u8' cannot represent value\n",
3101 "{f}",
3102 .{errors},
3103 );
3208 \\input.zon:1:1: error: type 'u8' cannot represent value
3209 \\
3210 , "{f}", .{errors.fmt("input.zon")});
31043211 }
31053212
31063213 // Negative integer zero
......@@ -3112,11 +3219,11 @@ test "std.zon parse int" {
31123219 .errors = &errors,
31133220 }));
31143221 try std.testing.expectFmt(
3115 \\1:2: error: integer literal '-0' is ambiguous
3116 \\1:2: note: use '0' for an integer zero
3117 \\1:2: note: use '-0.0' for a floating-point signed zero
3222 \\input.zon:1:2: error: integer literal '-0' is ambiguous
3223 \\input.zon:1:2: note: use '0' for an integer zero
3224 \\input.zon:1:2: note: use '-0.0' for a floating-point signed zero
31183225 \\
3119 , "{f}", .{errors});
3226 , "{f}", .{errors.fmt("input.zon")});
31203227 }
31213228
31223229 // Negative integer zero casted to float
......@@ -3128,11 +3235,11 @@ test "std.zon parse int" {
31283235 .errors = &errors,
31293236 }));
31303237 try std.testing.expectFmt(
3131 \\1:2: error: integer literal '-0' is ambiguous
3132 \\1:2: note: use '0' for an integer zero
3133 \\1:2: note: use '-0.0' for a floating-point signed zero
3238 \\input.zon:1:2: error: integer literal '-0' is ambiguous
3239 \\input.zon:1:2: note: use '0' for an integer zero
3240 \\input.zon:1:2: note: use '-0.0' for a floating-point signed zero
31343241 \\
3135 , "{f}", .{errors});
3242 , "{f}", .{errors.fmt("input.zon")});
31363243 }
31373244
31383245 // Negative float 0 is allowed
......@@ -3157,11 +3264,7 @@ test "std.zon parse int" {
31573264 .source = "--2",
31583265 .errors = &errors,
31593266 }));
3160 try std.testing.expectFmt(
3161 "1:1: error: expected number or 'inf' after '-'\n",
3162 "{f}",
3163 .{errors},
3164 );
3267 try std.testing.expectFmt("input.zon:1:1: error: expected number or 'inf' after '-'\n", "{f}", .{errors.fmt("input.zon")});
31653268 }
31663269
31673270 {
......@@ -3175,10 +3278,9 @@ test "std.zon parse int" {
31753278 }),
31763279 );
31773280 try std.testing.expectFmt(
3178 "1:1: error: expected number or 'inf' after '-'\n",
3179 "{f}",
3180 .{errors},
3181 );
3281 \\input.zon:1:1: error: expected number or 'inf' after '-'
3282 \\
3283 , "{f}", .{errors.fmt("input.zon")});
31823284 }
31833285
31843286 // Invalid int literal
......@@ -3189,7 +3291,10 @@ test "std.zon parse int" {
31893291 .source = "0xg",
31903292 .errors = &errors,
31913293 }));
3192 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{f}", .{errors});
3294 try std.testing.expectFmt(
3295 \\input.zon:1:3: error: invalid digit 'g' for hex base
3296 \\
3297 , "{f}", .{errors.fmt("input.zon")});
31933298 }
31943299
31953300 // Notes on invalid int literal
......@@ -3201,10 +3306,10 @@ test "std.zon parse int" {
32013306 .errors = &errors,
32023307 }));
32033308 try std.testing.expectFmt(
3204 \\1:1: error: number '0123' has leading zero
3205 \\1:1: note: use '0o' prefix for octal literals
3309 \\input.zon:1:1: error: number '0123' has leading zero
3310 \\input.zon:1:1: note: use '0o' prefix for octal literals
32063311 \\
3207 , "{f}", .{errors});
3312 , "{f}", .{errors.fmt("input.zon")});
32083313 }
32093314}
32103315
......@@ -3222,10 +3327,9 @@ test "std.zon negative char" {
32223327 .errors = &errors,
32233328 }));
32243329 try std.testing.expectFmt(
3225 "1:1: error: expected number or 'inf' after '-'\n",
3226 "{f}",
3227 .{errors},
3228 );
3330 \\input.zon:1:1: error: expected number or 'inf' after '-'
3331 \\
3332 , "{f}", .{errors.fmt("input.zon")});
32293333 }
32303334 {
32313335 var errors: Errors = .init(arena);
......@@ -3235,14 +3339,15 @@ test "std.zon negative char" {
32353339 .errors = &errors,
32363340 }));
32373341 try std.testing.expectFmt(
3238 "1:1: error: expected number or 'inf' after '-'\n",
3239 "{f}",
3240 .{errors},
3241 );
3342 \\input.zon:1:1: error: expected number or 'inf' after '-'
3343 \\
3344 , "{f}", .{errors.fmt("input.zon")});
32423345 }
32433346}
32443347
32453348test "std.zon parse float" {
3349 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
3350
32463351 const gpa = std.testing.allocator;
32473352 var arena_allocator: ArenaAllocator = .init(gpa);
32483353 defer arena_allocator.deinit();
......@@ -3399,11 +3504,7 @@ test "std.zon parse float" {
33993504 .source = "-nan",
34003505 .errors = &errors,
34013506 }));
3402 try std.testing.expectFmt(
3403 "1:1: error: expected number or 'inf' after '-'\n",
3404 "{f}",
3405 .{errors},
3406 );
3507 try std.testing.expectFmt("input.zon:1:1: error: expected number or 'inf' after '-'\n", "{f}", .{errors.fmt("input.zon")});
34073508 }
34083509
34093510 // nan as int not allowed
......@@ -3414,7 +3515,10 @@ test "std.zon parse float" {
34143515 .source = "nan",
34153516 .errors = &errors,
34163517 }));
3417 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{errors});
3518 try std.testing.expectFmt(
3519 \\input.zon:1:1: error: expected type 'i8'
3520 \\
3521 , "{f}", .{errors.fmt("input.zon")});
34183522 }
34193523
34203524 // nan as int not allowed
......@@ -3425,7 +3529,10 @@ test "std.zon parse float" {
34253529 .source = "nan",
34263530 .errors = &errors,
34273531 }));
3428 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{errors});
3532 try std.testing.expectFmt(
3533 \\input.zon:1:1: error: expected type 'i8'
3534 \\
3535 , "{f}", .{errors.fmt("input.zon")});
34293536 }
34303537
34313538 // inf as int not allowed
......@@ -3436,7 +3543,10 @@ test "std.zon parse float" {
34363543 .source = "inf",
34373544 .errors = &errors,
34383545 }));
3439 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{errors});
3546 try std.testing.expectFmt(
3547 \\input.zon:1:1: error: expected type 'i8'
3548 \\
3549 , "{f}", .{errors.fmt("input.zon")});
34403550 }
34413551
34423552 // -inf as int not allowed
......@@ -3447,7 +3557,10 @@ test "std.zon parse float" {
34473557 .source = "-inf",
34483558 .errors = &errors,
34493559 }));
3450 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{errors});
3560 try std.testing.expectFmt(
3561 \\input.zon:1:1: error: expected type 'i8'
3562 \\
3563 , "{f}", .{errors.fmt("input.zon")});
34513564 }
34523565
34533566 // Bad identifier as float
......@@ -3459,11 +3572,11 @@ test "std.zon parse float" {
34593572 .errors = &errors,
34603573 }));
34613574 try std.testing.expectFmt(
3462 \\1:1: error: invalid expression
3463 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
3464 \\1:1: note: precede identifier with '.' for an enum literal
3575 \\input.zon:1:1: error: invalid expression
3576 \\input.zon:1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
3577 \\input.zon:1:1: note: precede identifier with '.' for an enum literal
34653578 \\
3466 , "{f}", .{errors});
3579 , "{f}", .{errors.fmt("input.zon")});
34673580 }
34683581
34693582 {
......@@ -3474,10 +3587,9 @@ test "std.zon parse float" {
34743587 .errors = &errors,
34753588 }));
34763589 try std.testing.expectFmt(
3477 "1:1: error: expected number or 'inf' after '-'\n",
3478 "{f}",
3479 .{errors},
3480 );
3590 \\input.zon:1:1: error: expected number or 'inf' after '-'
3591 \\
3592 , "{f}", .{errors.fmt("input.zon")});
34813593 }
34823594
34833595 // Non float as float
......@@ -3491,7 +3603,10 @@ test "std.zon parse float" {
34913603 .errors = &errors,
34923604 }),
34933605 );
3494 try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{f}", .{errors});
3606 try std.testing.expectFmt(
3607 \\input.zon:1:1: error: expected type 'f32'
3608 \\
3609 , "{f}", .{errors.fmt("input.zon")});
34953610 }
34963611}
34973612
......@@ -3612,7 +3727,7 @@ test "std.zon free on error" {
36123727}
36133728
36143729test "std.zon vector" {
3615 const builtin = @import("builtin");
3730 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/15330
36163731 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .s390x) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/25957
36173732
36183733 const gpa = std.testing.allocator;
......@@ -3722,10 +3837,9 @@ test "std.zon vector" {
37223837 }),
37233838 );
37243839 try std.testing.expectFmt(
3725 "1:2: error: expected 2 array elements; found 1\n",
3726 "{f}",
3727 .{errors},
3728 );
3840 \\input.zon:1:2: error: expected 2 array elements; found 1
3841 \\
3842 , "{f}", .{errors.fmt("input.zon")});
37293843 }
37303844
37313845 // Too many fields
......@@ -3740,10 +3854,9 @@ test "std.zon vector" {
37403854 }),
37413855 );
37423856 try std.testing.expectFmt(
3743 "1:13: error: index 2 outside of array of length 2\n",
3744 "{f}",
3745 .{errors},
3746 );
3857 \\input.zon:1:13: error: index 2 outside of array of length 2
3858 \\
3859 , "{f}", .{errors.fmt("input.zon")});
37473860 }
37483861
37493862 // Wrong type fields
......@@ -3758,10 +3871,9 @@ test "std.zon vector" {
37583871 }),
37593872 );
37603873 try std.testing.expectFmt(
3761 "1:8: error: expected type 'f32'\n",
3762 "{f}",
3763 .{errors},
3764 );
3874 \\input.zon:1:8: error: expected type 'f32'
3875 \\
3876 , "{f}", .{errors.fmt("input.zon")});
37653877 }
37663878
37673879 // Wrong type
......@@ -3775,7 +3887,10 @@ test "std.zon vector" {
37753887 .errors = &errors,
37763888 }),
37773889 );
3778 try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{f}", .{errors});
3890 try std.testing.expectFmt(
3891 \\input.zon:1:1: error: expected type '@Vector(3, u8)'
3892 \\
3893 , "{f}", .{errors.fmt("input.zon")});
37793894 }
37803895
37813896 // Elements should get freed on error
......@@ -3790,7 +3905,10 @@ test "std.zon vector" {
37903905 .errors = &errors,
37913906 }),
37923907 );
3793 try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{f}", .{errors});
3908 try std.testing.expectFmt(
3909 \\input.zon:1:6: error: expected type 'u8'
3910 \\
3911 , "{f}", .{errors.fmt("input.zon")});
37943912 }
37953913}
37963914
......@@ -3981,7 +4099,10 @@ test "std.zon add pointers" {
39814099 .errors = &errors,
39824100 }),
39834101 );
3984 try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{f}", .{errors});
4102 try std.testing.expectFmt(
4103 \\input.zon:1:1: error: expected type '?u8'
4104 \\
4105 , "{f}", .{errors.fmt("input.zon")});
39854106 }
39864107
39874108 {
......@@ -3995,7 +4116,10 @@ test "std.zon add pointers" {
39954116 .errors = &errors,
39964117 }),
39974118 );
3998 try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{f}", .{errors});
4119 try std.testing.expectFmt(
4120 \\input.zon:1:1: error: expected type '?f32'
4121 \\
4122 , "{f}", .{errors.fmt("input.zon")});
39994123 }
40004124
40014125 {
......@@ -4009,7 +4133,10 @@ test "std.zon add pointers" {
40094133 .errors = &errors,
40104134 }),
40114135 );
4012 try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{f}", .{errors});
4136 try std.testing.expectFmt(
4137 \\input.zon:1:1: error: expected type '?@Vector(3, u8)'
4138 \\
4139 , "{f}", .{errors.fmt("input.zon")});
40134140 }
40144141
40154142 {
......@@ -4023,7 +4150,10 @@ test "std.zon add pointers" {
40234150 .errors = &errors,
40244151 }),
40254152 );
4026 try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{f}", .{errors});
4153 try std.testing.expectFmt(
4154 \\input.zon:1:1: error: expected type '?bool'
4155 \\
4156 , "{f}", .{errors.fmt("input.zon")});
40274157 }
40284158
40294159 {
......@@ -4037,7 +4167,10 @@ test "std.zon add pointers" {
40374167 .errors = &errors,
40384168 }),
40394169 );
4040 try std.testing.expectFmt("1:1: error: expected optional struct\n", "{f}", .{errors});
4170 try std.testing.expectFmt(
4171 \\input.zon:1:1: error: expected optional struct
4172 \\
4173 , "{f}", .{errors.fmt("input.zon")});
40414174 }
40424175
40434176 {
......@@ -4051,7 +4184,10 @@ test "std.zon add pointers" {
40514184 .errors = &errors,
40524185 }),
40534186 );
4054 try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{f}", .{errors});
4187 try std.testing.expectFmt(
4188 \\input.zon:1:1: error: expected optional tuple
4189 \\
4190 , "{f}", .{errors.fmt("input.zon")});
40554191 }
40564192
40574193 {
......@@ -4065,7 +4201,10 @@ test "std.zon add pointers" {
40654201 .errors = &errors,
40664202 }),
40674203 );
4068 try std.testing.expectFmt("1:1: error: expected optional union\n", "{f}", .{errors});
4204 try std.testing.expectFmt(
4205 \\input.zon:1:1: error: expected optional union
4206 \\
4207 , "{f}", .{errors.fmt("input.zon")});
40694208 }
40704209
40714210 {
......@@ -4079,7 +4218,10 @@ test "std.zon add pointers" {
40794218 .errors = &errors,
40804219 }),
40814220 );
4082 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{errors});
4221 try std.testing.expectFmt(
4222 \\input.zon:1:1: error: expected optional array
4223 \\
4224 , "{f}", .{errors.fmt("input.zon")});
40834225 }
40844226
40854227 {
......@@ -4093,7 +4235,10 @@ test "std.zon add pointers" {
40934235 .errors = &errors,
40944236 }),
40954237 );
4096 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{errors});
4238 try std.testing.expectFmt(
4239 \\input.zon:1:1: error: expected optional array
4240 \\
4241 , "{f}", .{errors.fmt("input.zon")});
40974242 }
40984243
40994244 {
......@@ -4107,7 +4252,10 @@ test "std.zon add pointers" {
41074252 .errors = &errors,
41084253 }),
41094254 );
4110 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{errors});
4255 try std.testing.expectFmt(
4256 \\input.zon:1:1: error: expected optional array
4257 \\
4258 , "{f}", .{errors.fmt("input.zon")});
41114259 }
41124260
41134261 {
......@@ -4121,7 +4269,10 @@ test "std.zon add pointers" {
41214269 .errors = &errors,
41224270 }),
41234271 );
4124 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{errors});
4272 try std.testing.expectFmt(
4273 \\input.zon:1:1: error: expected optional array
4274 \\
4275 , "{f}", .{errors.fmt("input.zon")});
41254276 }
41264277
41274278 {
......@@ -4135,7 +4286,10 @@ test "std.zon add pointers" {
41354286 .errors = &errors,
41364287 }),
41374288 );
4138 try std.testing.expectFmt("1:1: error: expected optional string\n", "{f}", .{errors});
4289 try std.testing.expectFmt(
4290 \\input.zon:1:1: error: expected optional string
4291 \\
4292 , "{f}", .{errors.fmt("input.zon")});
41394293 }
41404294
41414295 {
......@@ -4149,7 +4303,10 @@ test "std.zon add pointers" {
41494303 .errors = &errors,
41504304 }),
41514305 );
4152 try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{f}", .{errors});
4306 try std.testing.expectFmt(
4307 \\input.zon:1:1: error: expected optional enum literal
4308 \\
4309 , "{f}", .{errors.fmt("input.zon")});
41534310 }
41544311}
41554312
......@@ -4437,7 +4594,10 @@ test "std.zon update optionals" {
44374594 .source = ".{ .foo = .{} }",
44384595 .errors = &errors,
44394596 }));
4440 try std.testing.expectFmt("1:12: error: missing required field qux\n", "{f}", .{errors});
4597 try std.testing.expectFmt(
4598 \\input.zon:1:12: error: missing required field qux
4599 \\
4600 , "{f}", .{errors.fmt("input.zon")});
44414601 }
44424602
44434603 // Updating an optional that starts out non-null should preserve any values we leave off. It's
......@@ -4557,7 +4717,10 @@ test "std.zon update unions" {
45574717 .source = ".{ .foo = .{} }",
45584718 .errors = &errors,
45594719 }));
4560 try std.testing.expectFmt("1:12: error: missing required field qux\n", "{f}", .{errors});
4720 try std.testing.expectFmt(
4721 \\input.zon:1:12: error: missing required field qux
4722 \\
4723 , "{f}", .{errors.fmt("input.zon")});
45614724 }
45624725
45634726 // Updating a union should preseve any sub-fields that we left off. It's also okay to leave off