authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-08-07 17:50:51-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
loga6552e7d009883ae33a1b6aa24d216df6c964f17
tree9ac1a677dce56ed356f02e0f9f14f59341e26299
parente4a7988fec0d53e5f48a1701aeebacf192198203

Cleans up memory management and error reporting

- Use the same arena for errors and results - Store errors as a slice rather than an array list - Make the errors container non-optional - Rename functions like `fromSliceAlloc`/`fromSlice` to `fromSlice`/`fromSliceNoAlloc` - Cleans up error formatting and internal helper structure

1 files changed, 1012 insertions(+), 852 deletions(-)

lib/std/zon/parse.zig+1012-852
......@@ -1,7 +1,7 @@
1//! Use `fromSlice`/`fromSliceAlloc` to parse a ZON string into a Zig value. Human readable errors
1//! Use `fromSlice`/`fromSlice` to parse a ZON string into a Zig value. Human readable errors
22//! are written to an out parameter.
33//!
4//! If your data is already available in tree form, consider `fromZoir`/`fromZoirAlloc`.
4//! If your data is already available in tree form, consider `fromZoir`/`fromZoir`.
55//!
66//! To parse into an existing value, see the `updateFrom*` variants. For lower level control over
77//! parsing, see `std.zig.ZonGen`. For importing ZON at compile time, use `@import`.
......@@ -93,15 +93,9 @@ pub const Error = struct {
9393
9494/// Errors encountered while parsing ZON. See `log` and `fatal` for reporting errors to the user.
9595pub const Errors = struct {
96 arena: Allocator,
97 list: std.ArrayList(Error),
96 items: []const Error,
9897
99 pub fn init(arena: Allocator) Errors {
100 return .{
101 .arena = arena,
102 .list = .empty,
103 };
104 }
98 pub const empty: Errors = .{ .items = &.{} };
10599
106100 /// Log the failure with `std.log.err`.
107101 pub fn log(
......@@ -109,7 +103,7 @@ pub const Errors = struct {
109103 path: []const u8,
110104 err: error{ OutOfMemory, ParseZon },
111105 ) void {
112 std.log.err("{s}: {}\n{f}", .{ path, err, self.fmt(path) });
106 std.log.err("{f}", .{self.fmt(path, err)});
113107 }
114108
115109 test log {
......@@ -117,17 +111,18 @@ pub const Errors = struct {
117111 var arena_allocator: ArenaAllocator = .init(gpa);
118112 defer arena_allocator.deinit();
119113 const arena = arena_allocator.allocator();
114 var errors: Errors = .empty;
120115
121116 const MyType = struct {
122117 foo: u32,
123118 bar: u32,
124119 };
125120
126 const errors: Errors = .init(arena);
127 const parsed: MyType = fromSlice(MyType, .{
121 const parsed: MyType = fromSliceNoAlloc(MyType, .{
128122 .gpa = gpa,
123 .arena = arena,
129124 .source = ".{ .foo = 1, .bar = 2 }",
130 .errors = null,
125 .errors = &errors,
131126 }) catch |err| b: {
132127 errors.log("input.zon", err);
133128 break :b .{ .foo = 0, .bar = 0 };
......@@ -141,7 +136,7 @@ pub const Errors = struct {
141136 path: []const u8,
142137 err: error{ OutOfMemory, ParseZon },
143138 ) noreturn {
144 std.process.fatal("{s}: {}\n{f}", .{ path, err, self.fmt(path) });
139 std.process.fatal("{f}", .{self.fmt(path, err)});
145140 }
146141
147142 test fatal {
......@@ -149,34 +144,42 @@ pub const Errors = struct {
149144 var arena_allocator: ArenaAllocator = .init(gpa);
150145 defer arena_allocator.deinit();
151146 const arena = arena_allocator.allocator();
147 var errors: Errors = .empty;
152148
153149 const MyType = struct {
154150 foo: u32,
155151 bar: u32,
156152 };
157153
158 const errors: Errors = .init(arena);
159 const parsed = fromSlice(MyType, .{
154 const parsed = fromSliceNoAlloc(MyType, .{
160155 .gpa = gpa,
156 .arena = arena,
161157 .source = ".{ .foo = 1, .bar = 2 }",
162 .errors = null,
158 .errors = &errors,
163159 }) catch |err| errors.fatal("input.zon", err);
164160 _ = parsed;
165161 }
166162
167 pub fn fmt(self: *const Errors, path: []const u8) Formatter {
163 pub fn fmt(
164 self: *const Errors,
165 path: []const u8,
166 err: error{ OutOfMemory, ParseZon },
167 ) Formatter {
168168 return .{
169 .items = self.items,
169170 .path = path,
170 .errors = self.list.items,
171 .err = err,
171172 };
172173 }
173174
174175 pub const Formatter = struct {
175176 path: []const u8,
176 errors: []const Error,
177 items: []const Error,
178 err: error{ OutOfMemory, ParseZon },
177179
178180 pub fn format(self: *const @This(), w: *std.Io.Writer) std.Io.Writer.Error!void {
179 for (self.errors) |e| {
181 try w.print("{s}: {}\n", .{ self.path, self.err });
182 for (self.items) |e| {
180183 try w.print("{s}:", .{self.path});
181184 try w.print("{d}:{d}: error: {s}\n", .{
182185 e.loc.line + 1,
......@@ -200,263 +203,181 @@ pub const Errors = struct {
200203pub const FromSliceOptions = struct {
201204 /// Used for scratch allocations.
202205 gpa: Allocator,
206 /// Used for allocating errors and results.
207 arena: Allocator,
203208 /// The ZON source to parse.
204209 source: [:0]const u8,
205 /// If non-null, any errors encountered are appended here.
206 errors: ?*Errors,
210 /// When an error is returned from the parser, a human readable error description of the failure
211 /// is stored here.
212 errors: *Errors,
207213 /// If true, unknown fields do not error.
208214 ignore_unknown_fields: bool = false,
209215};
210216
211217/// Parses the given slice as ZON.
212218///
213/// Returns `error.OutOfMemory` on allocation failure, or `error.ParseZon` error if the ZON is
214/// invalid or can not be deserialized into type `T`.
215///
216/// When the parser returns `error.ParseZon`, it will also store a human readable explanation in
217/// `errors` if non null.
218///
219/// Asserts at compile time that the result type doesn't contain pointers. As such, the result
220/// doesn't need to be freed.
221///
222/// An allocator is still required for temporary allocations made during parsing.
219/// Human readable errors are written to `options.errors`. `options.arena` owns the errors, and any
220/// pointers that are part of `T`.
223221pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {
222 var value: T = undefined;
223 try fromSliceInner(T, &value, false, options);
224 return value;
225}
226
227/// Like `fromSlice` but the result type may not contain pointers, allowing it to outlive
228/// `options.arena`.
229pub fn fromSliceNoAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {
224230 comptime assert(!requiresAllocator(T));
225 return fromSliceAlloc(T, .{
226 .gpa = options.gpa,
227 .arena = .failing,
228 .source = options.source,
229 .errors = options.errors,
230 .ignore_unknown_fields = options.ignore_unknown_fields,
231 });
231 return fromSlice(T, options);
232232}
233233
234/// Similar to `fromSlice`, but updates `value` in place which is assumed to hold a valid value. Any
235/// unspecified fields are left unchanged.
234/// Similar to `fromSlice`, but updates `value` in place. `value` must be initialized before this
235/// call, fields not specified in ZON are left unchanged.
236236///
237/// Untagged unions and slices are replaced in their entiredy. If an error occurs while parsing,
238/// `value` remains valid but may be partially updated.
237/// Whenever a slice or an untagged union is specified, it completely overwites the previous value.
238/// On error, `value` remains valid, but may be partially updated.
239239pub fn updateFromSlice(
240240 T: type,
241241 value: *T,
242242 options: FromSliceOptions,
243243) error{ OutOfMemory, ParseZon }!void {
244 comptime assert(!requiresAllocator(T));
245 try updateFromSliceAlloc(T, value, .{
246 .gpa = options.gpa,
247 .arena = .failing,
248 .source = options.source,
249 .errors = options.errors,
250 .ignore_unknown_fields = options.ignore_unknown_fields,
251 });
252}
253
254pub const FromSliceAllocOptions = struct {
255 /// Used for scratch allocations.
256 gpa: Allocator,
257 /// Used for any allocations required by the out type.
258 arena: Allocator,
259 /// The ZON source to parse.
260 source: [:0]const u8,
261 /// If non-null, any errors encountered are appended here.
262 errors: ?*Errors,
263 /// If true, unknown fields do not error.
264 ignore_unknown_fields: bool = false,
265};
266
267/// Like `fromSlice`, but the result may contain pointers. To automatically free the result, see
268/// `free`.
269pub fn fromSliceAlloc(T: type, options: FromSliceAllocOptions) error{ OutOfMemory, ParseZon }!T {
270 var value: T = undefined;
271 try parseSliceAlloc(T, &value, .{
272 .gpa = options.gpa,
273 .arena = options.arena,
274 .source = options.source,
275 .errors = options.errors,
276 .ignore_unknown_fields = options.ignore_unknown_fields,
277 .initialized = false,
278 });
279 return value;
244 try fromSliceInner(T, value, true, options);
280245}
281246
282/// Like updateFromSlice`, but the result may contain pointers.
283pub fn updateFromSliceAlloc(
247/// Like `updateFromSlice` but the `T` may not contain pointers, allowing `value` to outlive
248/// `options.arena`.
249pub fn updateFromSliceNoAlloc(
284250 T: type,
285251 value: *T,
286 options: FromSliceAllocOptions,
252 options: FromSliceOptions,
287253) error{ OutOfMemory, ParseZon }!void {
288 try parseSliceAlloc(T, value, .{
289 .gpa = options.gpa,
290 .arena = options.arena,
291 .source = options.source,
292 .errors = options.errors,
293 .ignore_unknown_fields = options.ignore_unknown_fields,
294 .initialized = true,
295 });
254 comptime assert(!requiresAllocator(T));
255 try fromSliceInner(T, value, true, options);
296256}
297257
298const ParseSliceAllocOptions = struct {
299 gpa: Allocator,
300 arena: Allocator,
301 source: [:0]const u8,
302 errors: ?*Errors,
303 ignore_unknown_fields: bool,
304 initialized: bool,
305};
306
307fn parseSliceAlloc(
258fn fromSliceInner(
308259 T: type,
309260 value: *T,
310 options: ParseSliceAllocOptions,
261 initialized: bool,
262 options: FromSliceOptions,
311263) error{ OutOfMemory, ParseZon }!void {
264 var errors: std.ArrayList(Error) = .empty;
265 defer options.errors.items = errors.items;
266
312267 var ast = try std.zig.Ast.parse(options.gpa, options.source, .{ .mode = .zon });
313268 defer ast.deinit(options.gpa);
314269
315270 var zoir = try ZonGen.generate(options.gpa, ast, .{ .parse_str_lits = false });
316271 defer zoir.deinit(options.gpa);
317272
318 try parseZoirAlloc(T, value, .{
273 try inner(T, value, initialized, .{
319274 .arena = options.arena,
320275 .ast = &ast,
321276 .zoir = &zoir,
322277 .node = .root,
323 .errors = options.errors,
278 .errors = &errors,
324279 .ignore_unknown_fields = options.ignore_unknown_fields,
325 .initialized = options.initialized,
326280 });
327281}
328282
329283pub const FromZoirOptions = struct {
330 /// The AST for this this ZON value.
284 /// Used for allocating errors and results.
285 arena: Allocator,
286 /// The AST for this ZON value.
331287 ast: *const Ast,
332288 /// The zig object intermediate representation of this ZON value.
333289 zoir: *const Zoir,
334290 /// The node to start parsing at.
335291 node: Zoir.Node.Index = .root,
336 /// If non-null, any errors encountered are appended here.
337 errors: ?*Errors,
292 /// When an error is returned from the parser, a human readable error description of the failure
293 /// is stored here.
294 errors: *Errors,
338295 /// If true, unknown fields do not error.
339296 ignore_unknown_fields: bool = false,
340297};
341298
342299/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.
343pub fn fromZoir(T: type, options: FromZoirOptions) error{ParseZon}!T {
300pub fn fromZoir(T: type, options: FromZoirOptions) error{ OutOfMemory, ParseZon }!T {
301 var value: T = undefined;
302 try fromZoirInner(T, &value, false, options);
303 return value;
304}
305
306/// Like `fromSliceNoAlloc`, but operates on `Zoir` instead of ZON source.
307pub fn fromZoirNoAlloc(T: type, options: FromZoirOptions) error{ OutOfMemory, ParseZon }!T {
344308 comptime assert(!requiresAllocator(T));
345 return fromZoirAlloc(T, .{
346 .arena = .failing,
347 .ast = options.ast,
348 .zoir = options.zoir,
349 .node = options.node,
350 .errors = options.errors,
351 .ignore_unknown_fields = options.ignore_unknown_fields,
352 }) catch |err| switch (err) {
353 error.OutOfMemory => unreachable, // Checked by comptime assertion above
354 else => |e| return e,
355 };
309 return fromZoir(T, options);
356310}
357311
358/// Like `updateSlice`, but operates on `Zoir` instead of ZON source.
312/// Like `updateFromSlice`, but operates on `Zoir` instead of ZON source.
359313pub fn updateFromZoir(
360314 T: type,
361315 value: *T,
362316 options: FromZoirOptions,
363) error{ParseZon}!void {
364 comptime assert(!requiresAllocator(T));
365 updateFromZoirAlloc(T, value, .{
366 .arena = .failing,
367 .ast = options.ast,
368 .zoir = options.zoir,
369 .node = options.node,
370 .errors = options.errors,
371 .ignore_unknown_fields = options.ignore_unknown_fields,
372 }) catch |err| switch (err) {
373 error.OutOfMemory => unreachable, // Checked by comptime assertion above
374 else => |e| return e,
375 };
317) error{ OutOfMemory, ParseZon }!void {
318 return fromZoirInner(T, value, true, options);
376319}
377320
378pub const FromZoirAllocOptions = struct {
379 /// Used for any allocations required by the out type.
380 arena: Allocator,
381 /// The AST for this ZON value.
382 ast: *const Ast,
383 /// The zig object intermediate representation of this ZON value.
384 zoir: *const Zoir,
385 /// The node to start parsing at.
386 node: Zoir.Node.Index = .root,
387 /// If non-null, any errors encountered are appended here.
388 errors: ?*Errors,
389 /// If true, unknown fields do not error.
390 ignore_unknown_fields: bool = false,
391};
392
393/// Like `fromSliceAlloc`, but operates on `Zoir` instead of ZON source.
394pub fn fromZoirAlloc(T: type, options: FromZoirAllocOptions) error{ OutOfMemory, ParseZon }!T {
395 var value: T = undefined;
396 try parseZoirAlloc(T, &value, .{
397 .arena = options.arena,
398 .ast = options.ast,
399 .zoir = options.zoir,
400 .node = options.node,
401 .errors = options.errors,
402 .ignore_unknown_fields = options.ignore_unknown_fields,
403 .initialized = false,
404 });
405 return value;
321/// Like `updateFromSliceNoAlloc`, but operates on `Zoir` instead of ZON source.
322pub fn updateFromZoirNoAlloc(
323 T: type,
324 value: *T,
325 options: FromZoirOptions,
326) error{ OutOfMemory, ParseZon }!void {
327 comptime assert(!requiresAllocator(T));
328 return updateFromZoir(T, value, options);
406329}
407330
408/// Like updateSliceAlloc`, but operates on `Zoir` instead of ZON source.
409pub fn updateFromZoirAlloc(
331fn fromZoirInner(
410332 T: type,
411333 value: *T,
412 options: FromZoirAllocOptions,
334 initialized: bool,
335 options: FromZoirOptions,
413336) error{ OutOfMemory, ParseZon }!void {
414 return parseZoirAlloc(T, value, .{
337 var errors: std.ArrayList(Error) = .empty;
338 defer options.errors.items = errors.items;
339 return inner(T, value, initialized, .{
415340 .arena = options.arena,
416341 .ast = options.ast,
417342 .zoir = options.zoir,
418 .node = options.node,
419 .errors = options.errors,
343 .errors = &errors,
420344 .ignore_unknown_fields = options.ignore_unknown_fields,
421 .initialized = true,
422345 });
423346}
424347
425const ParseZoirAllocOptions = struct {
348const InnerOptions = struct {
426349 arena: Allocator,
427350 ast: *const Ast,
428351 zoir: *const Zoir,
429 node: Zoir.Node.Index,
430 errors: ?*Errors,
352 node: Zoir.Node.Index = .root,
353 errors: *std.ArrayList(Error),
431354 ignore_unknown_fields: bool,
432 initialized: bool,
433355};
434356
435fn parseZoirAlloc(
357fn inner(
436358 T: type,
437359 value: *T,
438 options: ParseZoirAllocOptions,
360 initialized: bool,
361 options: InnerOptions,
439362) error{ OutOfMemory, ParseZon }!void {
440363 comptime assert(canParseType(T));
441364
442365 if (options.zoir.hasCompileErrors()) {
443 if (options.errors) |errors| {
444 for (options.zoir.compile_errors) |e| {
445 var notes: std.ArrayList(Error.Note) = .empty;
446 for (e.getNotes(options.zoir)) |note| {
447 try notes.append(errors.arena, .init(options.ast, .{
448 .msg = try errors.arena.dupe(u8, note.msg.get(options.zoir)),
449 .token = note.token,
450 .node_or_offset = note.node_or_offset,
451 }));
452 }
453 try errors.list.append(errors.arena, .init(options.ast, .{
454 .msg = try errors.arena.dupe(u8, e.msg.get(options.zoir)),
455 .token = e.token,
456 .node_or_offset = e.node_or_offset,
457 .notes = try notes.toOwnedSlice(errors.arena),
366 for (options.zoir.compile_errors) |e| {
367 var notes: std.ArrayList(Error.Note) = .empty;
368 for (e.getNotes(options.zoir)) |note| {
369 try notes.append(options.arena, .init(options.ast, .{
370 .msg = try options.arena.dupe(u8, note.msg.get(options.zoir)),
371 .token = note.token,
372 .node_or_offset = note.node_or_offset,
458373 }));
459374 }
375 try options.errors.append(options.arena, .init(options.ast, .{
376 .msg = try options.arena.dupe(u8, e.msg.get(options.zoir)),
377 .token = e.token,
378 .node_or_offset = e.node_or_offset,
379 .notes = notes.items,
380 }));
460381 }
461382 return error.ParseZon;
462383 }
......@@ -469,7 +390,7 @@ fn parseZoirAlloc(
469390 .errors = options.errors,
470391 };
471392
472 try parser.parseExprInto(options.node, value, options.initialized);
393 try parser.parseExprInto(options.node, value, initialized);
473394}
474395
475396fn requiresAllocator(T: type) bool {
......@@ -497,7 +418,7 @@ const Parser = struct {
497418 arena: Allocator,
498419 ast: *const Ast,
499420 zoir: *const Zoir,
500 errors: ?*Errors,
421 errors: *std.ArrayList(Error),
501422 ignore_unknown_fields: bool,
502423
503424 const ParseExprError = error{ ParseZon, OutOfMemory };
......@@ -508,7 +429,7 @@ const Parser = struct {
508429 out: anytype,
509430 initialized: bool,
510431 ) ParseExprError!void {
511 return self.parseExprInnerInto(node, out, initialized) catch |err| switch (err) {
432 return self.parseExprIntoInner(node, out, initialized) catch |err| switch (err) {
512433 error.WrongType => return self.failExpectedType(@TypeOf(out.*), node),
513434 else => |e| return e,
514435 };
......@@ -516,7 +437,7 @@ const Parser = struct {
516437
517438 const ParseExprInnerError = error{ ParseZon, OutOfMemory, WrongType };
518439
519 fn parseExprInnerInto(
440 fn parseExprIntoInner(
520441 self: *@This(),
521442 node: Zoir.Node.Index,
522443 out: anytype,
......@@ -531,10 +452,10 @@ const Parser = struct {
531452 .optional => |optional| if (node.get(self.zoir) == .null) {
532453 out.* = null;
533454 } else if (initialized and out.* != null) {
534 try self.parseExprInnerInto(node, &out.*.?, true);
455 try self.parseExprIntoInner(node, &out.*.?, true);
535456 } else {
536457 var some: optional.child = undefined;
537 try self.parseExprInnerInto(node, &some, false);
458 try self.parseExprIntoInner(node, &some, false);
538459 out.* = some;
539460 },
540461 .bool => out.* = try self.parseBool(node),
......@@ -556,7 +477,7 @@ const Parser = struct {
556477 if (initialized) new.* = out.*.*;
557478 break :b new;
558479 };
559 try self.parseExprInnerInto(
480 try self.parseExprIntoInner(
560481 node,
561482 new,
562483 initialized,
......@@ -1072,10 +993,10 @@ const Parser = struct {
1072993 ) error{ OutOfMemory, ParseZon } {
1073994 @branchHint(.cold);
1074995 comptime assert(args.len > 0);
1075 if (self.errors) |errors| try errors.list.append(errors.arena, .init(self.ast, .{
996 try self.errors.append(self.arena, .init(self.ast, .{
1076997 .token = .fromToken(token),
1077998 .node_or_offset = offset,
1078 .msg = try std.fmt.allocPrint(errors.arena, fmt, args),
999 .msg = try std.fmt.allocPrint(self.arena, fmt, args),
10791000 .notes = notes,
10801001 }));
10811002 return error.ParseZon;
......@@ -1097,7 +1018,7 @@ const Parser = struct {
10971018 failure: Error,
10981019 ) error{ OutOfMemory, ParseZon } {
10991020 @branchHint(.cold);
1100 if (self.errors) |errors| try errors.list.append(errors.arena, failure);
1021 try self.errors.append(self.arena, failure);
11011022 return error.ParseZon;
11021023 }
11031024
......@@ -1134,7 +1055,6 @@ const Parser = struct {
11341055 name: []const u8,
11351056 ) error{ OutOfMemory, ParseZon } {
11361057 @branchHint(.cold);
1137 const errors = self.errors orelse return error.ParseZon;
11381058 const token = if (field) |f| b: {
11391059 var buf: [2]Ast.Node.Index = undefined;
11401060 const struct_init = self.ast.fullStructInit(&buf, node.getAstNode(self.zoir)).?;
......@@ -1145,13 +1065,13 @@ const Parser = struct {
11451065 inline .@"struct", .@"union", .@"enum" => |info| {
11461066 var notes: std.ArrayList(Error.Note) = .empty;
11471067 if (info.field_names.len == 0) {
1148 try notes.append(errors.arena, .init(self.ast, .{
1068 try notes.append(self.arena, .init(self.ast, .{
11491069 .token = .fromToken(token),
11501070 .node_or_offset = 0,
11511071 .msg = "none expected",
11521072 }));
11531073 } else {
1154 var aw: std.Io.Writer.Allocating = .init(errors.arena);
1074 var aw: std.Io.Writer.Allocating = .init(self.arena);
11551075 aw.writer.writeAll("supported: ") catch return error.OutOfMemory;
11561076 inline for (info.field_names, 0..) |field_name, i| {
11571077 if (i != 0) aw.writer.writeAll(", ") catch return error.OutOfMemory;
......@@ -1160,7 +1080,7 @@ const Parser = struct {
11601080 .allow_underscore = true,
11611081 })}) catch return error.OutOfMemory;
11621082 }
1163 try notes.append(errors.arena, .init(self.ast, .{
1083 try notes.append(self.arena, .init(self.ast, .{
11641084 .token = .fromToken(token),
11651085 .node_or_offset = 0,
11661086 .msg = try aw.toOwnedSlice(),
......@@ -1171,7 +1091,7 @@ const Parser = struct {
11711091 0,
11721092 "unexpected {s} '{s}'",
11731093 .{ item_kind, name },
1174 try notes.toOwnedSlice(errors.arena),
1094 notes.items,
11751095 );
11761096 },
11771097 else => comptime unreachable,
......@@ -1187,7 +1107,6 @@ const Parser = struct {
11871107 field: usize,
11881108 ) error{ OutOfMemory, ParseZon } {
11891109 @branchHint(.cold);
1190 if (self.errors == null) return error.ParseZon;
11911110 const ast_node = node.getAstNode(self.zoir);
11921111 var buf: [2]Ast.Node.Index = undefined;
11931112 const token = if (self.ast.fullStructInit(&buf, ast_node)) |struct_init| b: {
......@@ -1368,19 +1287,21 @@ test "std.zon ast errors" {
13681287 var arena_allocator: ArenaAllocator = .init(gpa);
13691288 defer arena_allocator.deinit();
13701289 const arena = arena_allocator.allocator();
1371 var errors: Errors = .init(arena);
1290 var errors: Errors = .empty;
13721291 try std.testing.expectError(
13731292 error.ParseZon,
1374 fromSlice(struct {}, .{
1293 fromSliceNoAlloc(struct {}, .{
13751294 .gpa = gpa,
1295 .arena = arena,
13761296 .source = ".{.x = 1 .y = 2}",
13771297 .errors = &errors,
13781298 }),
13791299 );
13801300 try std.testing.expectFmt(
1301 \\input.zon: error.ParseZon
13811302 \\input.zon:1:13: error: expected ',' after initializer
13821303 \\
1383 , "{f}", .{errors.fmt("input.zon")});
1304 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
13841305}
13851306
13861307test "std.zon comments" {
......@@ -1388,21 +1309,23 @@ test "std.zon comments" {
13881309 var arena_allocator: ArenaAllocator = .init(gpa);
13891310 defer arena_allocator.deinit();
13901311 const arena = arena_allocator.allocator();
1312 var errors: Errors = .empty;
13911313
1392 try std.testing.expectEqual(@as(u8, 10), fromSlice(u8, .{
1314 try std.testing.expectEqual(@as(u8, 10), fromSliceNoAlloc(u8, .{
13931315 .gpa = gpa,
1316 .arena = arena,
13941317 .source =
13951318 \\// comment
13961319 \\10 // comment
13971320 \\// comment
13981321 ,
1399 .errors = null,
1322 .errors = &errors,
14001323 }));
14011324
14021325 {
1403 var errors: Errors = .init(arena);
1404 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
1326 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
14051327 .gpa = gpa,
1328 .arena = arena,
14061329 .source =
14071330 \\//! comment
14081331 \\10 // comment
......@@ -1410,7 +1333,11 @@ test "std.zon comments" {
14101333 ,
14111334 .errors = &errors,
14121335 }));
1413 try std.testing.expectFmt("input.zon:1:1: error: expected expression, found 'a document comment'\n", "{f}", .{errors.fmt("input.zon")});
1336 try std.testing.expectFmt(
1337 \\input.zon: error.ParseZon
1338 \\input.zon:1:1: error: expected expression, found 'a document comment'
1339 \\
1340 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
14141341 }
14151342}
14161343
......@@ -1419,26 +1346,33 @@ test "std.zon failure/oom formatting" {
14191346 var arena_allocator: ArenaAllocator = .init(gpa);
14201347 defer arena_allocator.deinit();
14211348 const arena = arena_allocator.allocator();
1422 var errors: Errors = .init(arena);
1423 try std.testing.expectError(error.OutOfMemory, fromSliceAlloc([]const u8, .{
1349 var errors: Errors = .empty;
1350
1351 try std.testing.expectError(error.OutOfMemory, fromSlice([]const u8, .{
14241352 .gpa = .failing,
14251353 .arena = arena,
14261354 .source = "\"foo\"",
14271355 .errors = &errors,
14281356 }));
14291357 try std.testing.expectFmt(
1358 \\input.zon: error.ParseZon
14301359 \\
1431 , "{f}", .{errors.fmt("input.zon")});
1360 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
14321361}
14331362
1434test "std.zon fromSliceAlloc syntax error" {
1363test "std.zon fromSlice syntax error" {
14351364 const gpa = std.testing.allocator;
1365 var arena_allocator: ArenaAllocator = .init(gpa);
1366 defer arena_allocator.deinit();
1367 const arena = arena_allocator.allocator();
1368 var errors: Errors = .empty;
14361369 try std.testing.expectError(
14371370 error.ParseZon,
1438 fromSlice(u8, .{
1371 fromSliceNoAlloc(u8, .{
14391372 .gpa = gpa,
1373 .arena = arena,
14401374 .source = ".{",
1441 .errors = null,
1375 .errors = &errors,
14421376 }),
14431377 );
14441378}
......@@ -1448,37 +1382,40 @@ test "std.zon optional" {
14481382 var arena_allocator: ArenaAllocator = .init(gpa);
14491383 defer arena_allocator.deinit();
14501384 const arena = arena_allocator.allocator();
1385 var errors: Errors = .empty;
14511386
14521387 // Basic usage
14531388 {
1454 const none = try fromSlice(?u32, .{
1389 const none = try fromSliceNoAlloc(?u32, .{
14551390 .gpa = gpa,
1391 .arena = arena,
14561392 .source = "null",
1457 .errors = null,
1393 .errors = &errors,
14581394 });
14591395 try std.testing.expect(none == null);
1460 const some = try fromSlice(?u32, .{
1396 const some = try fromSliceNoAlloc(?u32, .{
14611397 .gpa = gpa,
1398 .arena = arena,
14621399 .source = "1",
1463 .errors = null,
1400 .errors = &errors,
14641401 });
14651402 try std.testing.expect(some.? == 1);
14661403 }
14671404
14681405 // Deep free
14691406 {
1470 const none = try fromSliceAlloc(?[]const u8, .{
1407 const none = try fromSlice(?[]const u8, .{
14711408 .gpa = gpa,
14721409 .arena = arena,
14731410 .source = "null",
1474 .errors = null,
1411 .errors = &errors,
14751412 });
14761413 try std.testing.expect(none == null);
1477 const some = try fromSliceAlloc(?[]const u8, .{
1414 const some = try fromSlice(?[]const u8, .{
14781415 .gpa = gpa,
14791416 .arena = arena,
14801417 .source = "\"foo\"",
1481 .errors = null,
1418 .errors = &errors,
14821419 });
14831420 try std.testing.expectEqualStrings("foo", some.?);
14841421 }
......@@ -1489,47 +1426,54 @@ test "std.zon unions" {
14891426 var arena_allocator: ArenaAllocator = .init(gpa);
14901427 defer arena_allocator.deinit();
14911428 const arena = arena_allocator.allocator();
1429 var errors: Errors = .empty;
14921430
14931431 // Unions
14941432 {
14951433 const Tagged = union(enum) { x: f32, @"y y": bool, z, @"z z" };
14961434 const Untagged = union { x: f32, @"y y": bool, z: void, @"z z": void };
14971435
1498 const tagged_x = try fromSlice(Tagged, .{
1436 const tagged_x = try fromSliceNoAlloc(Tagged, .{
14991437 .gpa = gpa,
1438 .arena = arena,
15001439 .source = ".{.x = 1.5}",
1501 .errors = null,
1440 .errors = &errors,
15021441 });
15031442 try std.testing.expectEqual(Tagged{ .x = 1.5 }, tagged_x);
1504 const tagged_y = try fromSlice(Tagged, .{
1443 const tagged_y = try fromSliceNoAlloc(Tagged, .{
15051444 .gpa = gpa,
1445 .arena = arena,
15061446 .source = ".{.@\"y y\" = true}",
1507 .errors = null,
1447 .errors = &errors,
15081448 });
15091449 try std.testing.expectEqual(Tagged{ .@"y y" = true }, tagged_y);
1510 const tagged_z_shorthand = try fromSlice(Tagged, .{
1450 const tagged_z_shorthand = try fromSliceNoAlloc(Tagged, .{
15111451 .gpa = gpa,
1452 .arena = arena,
15121453 .source = ".z",
1513 .errors = null,
1454 .errors = &errors,
15141455 });
15151456 try std.testing.expectEqual(@as(Tagged, .z), tagged_z_shorthand);
1516 const tagged_zz_shorthand = try fromSlice(Tagged, .{
1457 const tagged_zz_shorthand = try fromSliceNoAlloc(Tagged, .{
15171458 .gpa = gpa,
1459 .arena = arena,
15181460 .source = ".@\"z z\"",
1519 .errors = null,
1461 .errors = &errors,
15201462 });
15211463 try std.testing.expectEqual(@as(Tagged, .@"z z"), tagged_zz_shorthand);
15221464
1523 const untagged_x = try fromSlice(Untagged, .{
1465 const untagged_x = try fromSliceNoAlloc(Untagged, .{
15241466 .gpa = gpa,
1467 .arena = arena,
15251468 .source = ".{.x = 1.5}",
1526 .errors = null,
1469 .errors = &errors,
15271470 });
15281471 try std.testing.expect(untagged_x.x == 1.5);
1529 const untagged_y = try fromSlice(Untagged, .{
1472 const untagged_y = try fromSliceNoAlloc(Untagged, .{
15301473 .gpa = gpa,
1474 .arena = arena,
15311475 .source = ".{.@\"y y\" = true}",
1532 .errors = null,
1476 .errors = &errors,
15331477 });
15341478 try std.testing.expect(untagged_y.@"y y");
15351479 }
......@@ -1538,19 +1482,19 @@ test "std.zon unions" {
15381482 {
15391483 const Union = union(enum) { bar: []const u8, baz: bool };
15401484
1541 const noalloc = try fromSliceAlloc(Union, .{
1485 const noalloc = try fromSlice(Union, .{
15421486 .gpa = gpa,
15431487 .arena = arena,
15441488 .source = ".{.baz = false}",
1545 .errors = null,
1489 .errors = &errors,
15461490 });
15471491 try std.testing.expectEqual(Union{ .baz = false }, noalloc);
15481492
1549 const alloc = try fromSliceAlloc(Union, .{
1493 const alloc = try fromSlice(Union, .{
15501494 .gpa = gpa,
15511495 .arena = arena,
15521496 .source = ".{.bar = \"qux\"}",
1553 .errors = null,
1497 .errors = &errors,
15541498 });
15551499 try std.testing.expectEqualDeep(Union{ .bar = "qux" }, alloc);
15561500 }
......@@ -1558,10 +1502,9 @@ test "std.zon unions" {
15581502 // Unknown field
15591503 {
15601504 const Union = union { x: f32, y: f32 };
1561 var errors: Errors = .init(arena);
15621505 try std.testing.expectError(
15631506 error.ParseZon,
1564 fromSliceAlloc(Union, .{
1507 fromSlice(Union, .{
15651508 .gpa = gpa,
15661509 .arena = arena,
15671510 .source = ".{.z=2.5}",
......@@ -1569,19 +1512,19 @@ test "std.zon unions" {
15691512 }),
15701513 );
15711514 try std.testing.expectFmt(
1515 \\input.zon: error.ParseZon
15721516 \\input.zon:1:4: error: unexpected field 'z'
15731517 \\input.zon:1:4: note: supported: 'x', 'y'
15741518 \\
1575 , "{f}", .{errors.fmt("input.zon")});
1519 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
15761520 }
15771521
15781522 // Explicit void field
15791523 {
15801524 const Union = union(enum) { x: void };
1581 var errors: Errors = .init(arena);
15821525 try std.testing.expectError(
15831526 error.ParseZon,
1584 fromSliceAlloc(Union, .{
1527 fromSlice(Union, .{
15851528 .gpa = gpa,
15861529 .arena = arena,
15871530 .source = ".{.x=1}",
......@@ -1589,18 +1532,18 @@ test "std.zon unions" {
15891532 }),
15901533 );
15911534 try std.testing.expectFmt(
1535 \\input.zon: error.ParseZon
15921536 \\input.zon:1:6: error: expected type 'void'
15931537 \\
1594 , "{f}", .{errors.fmt("input.zon")});
1538 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
15951539 }
15961540
15971541 // Extra field
15981542 {
15991543 const Union = union { x: f32, y: bool };
1600 var errors: Errors = .init(arena);
16011544 try std.testing.expectError(
16021545 error.ParseZon,
1603 fromSliceAlloc(Union, .{
1546 fromSlice(Union, .{
16041547 .gpa = gpa,
16051548 .arena = arena,
16061549 .source = ".{.x = 1.5, .y = true}",
......@@ -1608,18 +1551,18 @@ test "std.zon unions" {
16081551 }),
16091552 );
16101553 try std.testing.expectFmt(
1554 \\input.zon: error.ParseZon
16111555 \\input.zon:1:2: error: expected union
16121556 \\
1613 , "{f}", .{errors.fmt("input.zon")});
1557 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
16141558 }
16151559
16161560 // No fields
16171561 {
16181562 const Union = union { x: f32, y: bool };
1619 var errors: Errors = .init(arena);
16201563 try std.testing.expectError(
16211564 error.ParseZon,
1622 fromSliceAlloc(Union, .{
1565 fromSlice(Union, .{
16231566 .gpa = gpa,
16241567 .arena = arena,
16251568 .source = ".{}",
......@@ -1627,58 +1570,59 @@ test "std.zon unions" {
16271570 }),
16281571 );
16291572 try std.testing.expectFmt(
1573 \\input.zon: error.ParseZon
16301574 \\input.zon:1:2: error: expected union
16311575 \\
1632 , "{f}", .{errors.fmt("input.zon")});
1576 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
16331577 }
16341578
16351579 // Enum literals cannot coerce into untagged unions
16361580 {
16371581 const Union = union { x: void };
1638 var errors: Errors = .init(arena);
1639 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1582 try std.testing.expectError(error.ParseZon, fromSlice(Union, .{
16401583 .gpa = gpa,
16411584 .arena = arena,
16421585 .source = ".x",
16431586 .errors = &errors,
16441587 }));
16451588 try std.testing.expectFmt(
1589 \\input.zon: error.ParseZon
16461590 \\input.zon:1:2: error: expected union
16471591 \\
1648 , "{f}", .{errors.fmt("input.zon")});
1592 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
16491593 }
16501594
16511595 // Unknown field for enum literal coercion
16521596 {
16531597 const Union = union(enum) { x: void };
1654 var errors: Errors = .init(arena);
1655 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1598 try std.testing.expectError(error.ParseZon, fromSlice(Union, .{
16561599 .gpa = gpa,
16571600 .arena = arena,
16581601 .source = ".y",
16591602 .errors = &errors,
16601603 }));
16611604 try std.testing.expectFmt(
1605 \\input.zon: error.ParseZon
16621606 \\input.zon:1:2: error: unexpected field 'y'
16631607 \\input.zon:1:2: note: supported: 'x'
16641608 \\
1665 , "{f}", .{errors.fmt("input.zon")});
1609 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
16661610 }
16671611
16681612 // Non void field for enum literal coercion
16691613 {
16701614 const Union = union(enum) { x: f32 };
1671 var errors: Errors = .init(arena);
1672 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1615 try std.testing.expectError(error.ParseZon, fromSlice(Union, .{
16731616 .gpa = gpa,
16741617 .arena = arena,
16751618 .source = ".x",
16761619 .errors = &errors,
16771620 }));
16781621 try std.testing.expectFmt(
1622 \\input.zon: error.ParseZon
16791623 \\input.zon:1:2: error: expected union
16801624 \\
1681 , "{f}", .{errors.fmt("input.zon")});
1625 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
16821626 }
16831627}
16841628
......@@ -1687,6 +1631,7 @@ test "std.zon structs" {
16871631 var arena_allocator: ArenaAllocator = .init(gpa);
16881632 defer arena_allocator.deinit();
16891633 const arena = arena_allocator.allocator();
1634 var errors: Errors = .empty;
16901635
16911636 // Structs (various sizes tested since they're parsed differently)
16921637 {
......@@ -1695,31 +1640,35 @@ test "std.zon structs" {
16951640 const Vec2 = struct { x: f32, y: f32 };
16961641 const Vec3 = struct { x: f32, y: f32, z: f32 };
16971642
1698 const zero = try fromSlice(Vec0, .{
1643 const zero = try fromSliceNoAlloc(Vec0, .{
16991644 .gpa = gpa,
1645 .arena = arena,
17001646 .source = ".{}",
1701 .errors = null,
1647 .errors = &errors,
17021648 });
17031649 try std.testing.expectEqual(Vec0{}, zero);
17041650
1705 const one = try fromSlice(Vec1, .{
1651 const one = try fromSliceNoAlloc(Vec1, .{
17061652 .gpa = gpa,
1653 .arena = arena,
17071654 .source = ".{.x = 1.2}",
1708 .errors = null,
1655 .errors = &errors,
17091656 });
17101657 try std.testing.expectEqual(Vec1{ .x = 1.2 }, one);
17111658
1712 const two = try fromSlice(Vec2, .{
1659 const two = try fromSliceNoAlloc(Vec2, .{
17131660 .gpa = gpa,
1661 .arena = arena,
17141662 .source = ".{.x = 1.2, .y = 3.4}",
1715 .errors = null,
1663 .errors = &errors,
17161664 });
17171665 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 3.4 }, two);
17181666
1719 const three = try fromSlice(Vec3, .{
1667 const three = try fromSliceNoAlloc(Vec3, .{
17201668 .gpa = gpa,
1669 .arena = arena,
17211670 .source = ".{.x = 1.2, .y = 3.4, .z = 5.6}",
1722 .errors = null,
1671 .errors = &errors,
17231672 });
17241673 try std.testing.expectEqual(Vec3{ .x = 1.2, .y = 3.4, .z = 5.6 }, three);
17251674 }
......@@ -1728,11 +1677,11 @@ test "std.zon structs" {
17281677 {
17291678 const Foo = struct { bar: []const u8, baz: []const []const u8 };
17301679
1731 const parsed = try fromSliceAlloc(Foo, .{
1680 const parsed = try fromSlice(Foo, .{
17321681 .gpa = gpa,
17331682 .arena = arena,
17341683 .source = ".{.bar = \"qux\", .baz = .{\"a\", \"b\"}}",
1735 .errors = null,
1684 .errors = &errors,
17361685 });
17371686 try std.testing.expectEqualDeep(Foo{ .bar = "qux", .baz = &.{ "a", "b" } }, parsed);
17381687 }
......@@ -1740,49 +1689,52 @@ test "std.zon structs" {
17401689 // Unknown field
17411690 {
17421691 const Vec2 = struct { x: f32, y: f32 };
1743 var errors: Errors = .init(arena);
17441692 try std.testing.expectError(
17451693 error.ParseZon,
1746 fromSlice(Vec2, .{
1694 fromSliceNoAlloc(Vec2, .{
17471695 .gpa = gpa,
1696 .arena = arena,
17481697 .source = ".{.x=1.5, .z=2.5}",
17491698 .errors = &errors,
17501699 }),
17511700 );
17521701 try std.testing.expectFmt(
1702 \\input.zon: error.ParseZon
17531703 \\input.zon:1:12: error: unexpected field 'z'
17541704 \\input.zon:1:12: note: supported: 'x', 'y'
17551705 \\
1756 , "{f}", .{errors.fmt("input.zon")});
1706 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
17571707 }
17581708
17591709 // Duplicate field
17601710 {
17611711 const Vec2 = struct { x: f32, y: f32 };
1762 var errors: Errors = .init(arena);
17631712 try std.testing.expectError(
17641713 error.ParseZon,
1765 fromSlice(Vec2, .{
1714 fromSliceNoAlloc(Vec2, .{
17661715 .gpa = gpa,
1716 .arena = arena,
17671717 .source = ".{.x=1.5, .x=2.5, .x=3.5}",
17681718 .errors = &errors,
17691719 }),
17701720 );
17711721 try std.testing.expectFmt(
1722 \\input.zon: error.ParseZon
17721723 \\input.zon:1:4: error: duplicate struct field name
17731724 \\input.zon:1:12: note: duplicate name here
17741725 \\
1775 , "{f}", .{errors.fmt("input.zon")});
1726 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
17761727 }
17771728
17781729 // Ignore unknown fields
17791730 {
17801731 const Vec2 = struct { x: f32, y: f32 = 2.0 };
1781 const parsed = try fromSlice(Vec2, .{
1732 const parsed = try fromSliceNoAlloc(Vec2, .{
17821733 .gpa = gpa,
1734 .arena = arena,
17831735 .source = ".{ .x = 1.0, .z = 3.0 }",
17841736 .ignore_unknown_fields = true,
1785 .errors = null,
1737 .errors = &errors,
17861738 });
17871739 try std.testing.expectEqual(Vec2{ .x = 1.0, .y = 2.0 }, parsed);
17881740 }
......@@ -1790,47 +1742,50 @@ test "std.zon structs" {
17901742 // Unknown field when struct has no fields (regression test)
17911743 {
17921744 const Vec2 = struct {};
1793 var errors: Errors = .init(arena);
17941745 try std.testing.expectError(
17951746 error.ParseZon,
1796 fromSlice(Vec2, .{
1747 fromSliceNoAlloc(Vec2, .{
17971748 .gpa = gpa,
1749 .arena = arena,
17981750 .source = ".{.x=1.5, .z=2.5}",
17991751 .errors = &errors,
18001752 }),
18011753 );
18021754 try std.testing.expectFmt(
1755 \\input.zon: error.ParseZon
18031756 \\input.zon:1:4: error: unexpected field 'x'
18041757 \\input.zon:1:4: note: none expected
18051758 \\
1806 , "{f}", .{errors.fmt("input.zon")});
1759 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
18071760 }
18081761
18091762 // Missing field
18101763 {
18111764 const Vec2 = struct { x: f32, y: f32 };
1812 var errors: Errors = .init(arena);
18131765 try std.testing.expectError(
18141766 error.ParseZon,
1815 fromSlice(Vec2, .{
1767 fromSliceNoAlloc(Vec2, .{
18161768 .gpa = gpa,
1769 .arena = arena,
18171770 .source = ".{.x=1.5}",
18181771 .errors = &errors,
18191772 }),
18201773 );
18211774 try std.testing.expectFmt(
1775 \\input.zon: error.ParseZon
18221776 \\input.zon:1:2: error: missing required field y
18231777 \\
1824 , "{f}", .{errors.fmt("input.zon")});
1778 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
18251779 }
18261780
18271781 // Default field
18281782 {
18291783 const Vec2 = struct { x: f32, y: f32 = 1.5 };
1830 const parsed = try fromSlice(Vec2, .{
1784 const parsed = try fromSliceNoAlloc(Vec2, .{
18311785 .gpa = gpa,
1786 .arena = arena,
18321787 .source = ".{.x = 1.2}",
1833 .errors = null,
1788 .errors = &errors,
18341789 });
18351790 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);
18361791 }
......@@ -1838,10 +1793,11 @@ test "std.zon structs" {
18381793 // Comptime field
18391794 {
18401795 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1841 const parsed = try fromSlice(Vec2, .{
1796 const parsed = try fromSliceNoAlloc(Vec2, .{
18421797 .gpa = gpa,
1798 .arena = arena,
18431799 .source = ".{.x = 1.2}",
1844 .errors = null,
1800 .errors = &errors,
18451801 });
18461802 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);
18471803 }
......@@ -1849,27 +1805,29 @@ test "std.zon structs" {
18491805 // Comptime field assignment
18501806 {
18511807 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1852 var errors: Errors = .init(arena);
1853 const parsed = fromSlice(Vec2, .{
1808 const parsed = fromSliceNoAlloc(Vec2, .{
18541809 .gpa = gpa,
1810 .arena = arena,
18551811 .source = ".{.x = 1.2, .y = 1.5}",
18561812 .errors = &errors,
18571813 });
18581814 try std.testing.expectError(error.ParseZon, parsed);
18591815 try std.testing.expectFmt(
1816 \\input.zon: error.ParseZon
18601817 \\input.zon:1:18: error: cannot initialize comptime field
18611818 \\
1862 , "{f}", .{errors.fmt("input.zon")});
1819 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
18631820 }
18641821
18651822 // Enum field (regression test, we were previously getting the field name in an
18661823 // incorrect way that broke for enum values)
18671824 {
18681825 const Vec0 = struct { x: enum { x } };
1869 const parsed = try fromSlice(Vec0, .{
1826 const parsed = try fromSliceNoAlloc(Vec0, .{
18701827 .gpa = gpa,
1828 .arena = arena,
18711829 .source = ".{ .x = .x }",
1872 .errors = null,
1830 .errors = &errors,
18731831 });
18741832 try std.testing.expectEqual(Vec0{ .x = .x }, parsed);
18751833 }
......@@ -1877,10 +1835,11 @@ test "std.zon structs" {
18771835 // Enum field and struct field with @
18781836 {
18791837 const Vec0 = struct { @"x x": enum { @"x x" } };
1880 const parsed = try fromSlice(Vec0, .{
1838 const parsed = try fromSliceNoAlloc(Vec0, .{
18811839 .gpa = gpa,
1840 .arena = arena,
18821841 .source = ".{ .@\"x x\" = .@\"x x\" }",
1883 .errors = null,
1842 .errors = &errors,
18841843 });
18851844 try std.testing.expectEqual(Vec0{ .@"x x" = .@"x x" }, parsed);
18861845 }
......@@ -1889,40 +1848,41 @@ test "std.zon structs" {
18891848 {
18901849 // Structs
18911850 {
1892 var errors: Errors = .init(arena);
1893 const parsed = fromSlice(struct {}, .{
1851 const parsed = fromSliceNoAlloc(struct {}, .{
18941852 .gpa = gpa,
1853 .arena = arena,
18951854 .source = "Empty{}",
18961855 .errors = &errors,
18971856 });
18981857 try std.testing.expectError(error.ParseZon, parsed);
18991858 try std.testing.expectFmt(
1859 \\input.zon: error.ParseZon
19001860 \\input.zon:1:1: error: types are not available in ZON
19011861 \\input.zon:1:1: note: replace the type with '.'
19021862 \\
1903 , "{f}", .{errors.fmt("input.zon")});
1863 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
19041864 }
19051865
19061866 // Arrays
19071867 {
1908 var errors: Errors = .init(arena);
1909 const parsed = fromSlice([3]u8, .{
1868 const parsed = fromSliceNoAlloc([3]u8, .{
19101869 .gpa = gpa,
1870 .arena = arena,
19111871 .source = "[3]u8{1, 2, 3}",
19121872 .errors = &errors,
19131873 });
19141874 try std.testing.expectError(error.ParseZon, parsed);
19151875 try std.testing.expectFmt(
1876 \\input.zon: error.ParseZon
19161877 \\input.zon:1:1: error: types are not available in ZON
19171878 \\input.zon:1:1: note: replace the type with '.'
19181879 \\
1919 , "{f}", .{errors.fmt("input.zon")});
1880 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
19201881 }
19211882
19221883 // Slices
19231884 {
1924 var errors: Errors = .init(arena);
1925 const parsed = fromSliceAlloc([]u8, .{
1885 const parsed = fromSlice([]u8, .{
19261886 .gpa = gpa,
19271887 .arena = arena,
19281888 .source = "[]u8{1, 2, 3}",
......@@ -1930,42 +1890,45 @@ test "std.zon structs" {
19301890 });
19311891 try std.testing.expectError(error.ParseZon, parsed);
19321892 try std.testing.expectFmt(
1893 \\input.zon: error.ParseZon
19331894 \\input.zon:1:1: error: types are not available in ZON
19341895 \\input.zon:1:1: note: replace the type with '.'
19351896 \\
1936 , "{f}", .{errors.fmt("input.zon")});
1897 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
19371898 }
19381899
19391900 // Tuples
19401901 {
1941 var errors: Errors = .init(arena);
1942 const parsed = fromSlice(struct { u8, u8, u8 }, .{
1902 const parsed = fromSliceNoAlloc(struct { u8, u8, u8 }, .{
19431903 .gpa = gpa,
1904 .arena = arena,
19441905 .source = "Tuple{1, 2, 3}",
19451906 .errors = &errors,
19461907 });
19471908 try std.testing.expectError(error.ParseZon, parsed);
19481909 try std.testing.expectFmt(
1910 \\input.zon: error.ParseZon
19491911 \\input.zon:1:1: error: types are not available in ZON
19501912 \\input.zon:1:1: note: replace the type with '.'
19511913 \\
1952 , "{f}", .{errors.fmt("input.zon")});
1914 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
19531915 }
19541916
19551917 // Nested
19561918 {
1957 var errors: Errors = .init(arena);
1958 const parsed = fromSlice(struct {}, .{
1919 const parsed = fromSliceNoAlloc(struct {}, .{
19591920 .gpa = gpa,
1921 .arena = arena,
19601922 .source = ".{ .x = Tuple{1, 2, 3} }",
19611923 .errors = &errors,
19621924 });
19631925 try std.testing.expectError(error.ParseZon, parsed);
19641926 try std.testing.expectFmt(
1927 \\input.zon: error.ParseZon
19651928 \\input.zon:1:9: error: types are not available in ZON
19661929 \\input.zon:1:9: note: replace the type with '.'
19671930 \\
1968 , "{f}", .{errors.fmt("input.zon")});
1931 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
19691932 }
19701933 }
19711934}
......@@ -1975,6 +1938,7 @@ test "std.zon tuples" {
19751938 var arena_allocator: ArenaAllocator = .init(gpa);
19761939 defer arena_allocator.deinit();
19771940 const arena = arena_allocator.allocator();
1941 var errors: Errors = .empty;
19781942
19791943 // Structs (various sizes tested since they're parsed differently)
19801944 {
......@@ -1983,31 +1947,35 @@ test "std.zon tuples" {
19831947 const Tuple2 = struct { f32, bool };
19841948 const Tuple3 = struct { f32, bool, u8 };
19851949
1986 const zero = try fromSlice(Tuple0, .{
1950 const zero = try fromSliceNoAlloc(Tuple0, .{
19871951 .gpa = gpa,
1952 .arena = arena,
19881953 .source = ".{}",
1989 .errors = null,
1954 .errors = &errors,
19901955 });
19911956 try std.testing.expectEqual(Tuple0{}, zero);
19921957
1993 const one = try fromSlice(Tuple1, .{
1958 const one = try fromSliceNoAlloc(Tuple1, .{
19941959 .gpa = gpa,
1960 .arena = arena,
19951961 .source = ".{1.2}",
1996 .errors = null,
1962 .errors = &errors,
19971963 });
19981964 try std.testing.expectEqual(Tuple1{1.2}, one);
19991965
2000 const two = try fromSlice(Tuple2, .{
1966 const two = try fromSliceNoAlloc(Tuple2, .{
20011967 .gpa = gpa,
1968 .arena = arena,
20021969 .source = ".{1.2, true}",
2003 .errors = null,
1970 .errors = &errors,
20041971 });
20051972 try std.testing.expectEqual(Tuple2{ 1.2, true }, two);
20061973
2007 const three = try fromSlice(Tuple3, .{
1974 const three = try fromSliceNoAlloc(Tuple3, .{
20081975 .gpa = gpa,
1976 .arena = arena,
20091977 .source = ".{1.2, false, 3}",
2010 .errors = null,
1978 .errors = &errors,
20111979 });
20121980 try std.testing.expectEqual(Tuple3{ 1.2, false, 3 }, three);
20131981 }
......@@ -2015,11 +1983,11 @@ test "std.zon tuples" {
20151983 // Deep free
20161984 {
20171985 const Tuple = struct { []const u8, []const u8 };
2018 const parsed = try fromSliceAlloc(Tuple, .{
1986 const parsed = try fromSlice(Tuple, .{
20191987 .gpa = gpa,
20201988 .arena = arena,
20211989 .source = ".{\"hello\", \"world\"}",
2022 .errors = null,
1990 .errors = &errors,
20231991 });
20241992 try std.testing.expectEqualDeep(Tuple{ "hello", "world" }, parsed);
20251993 }
......@@ -2027,79 +1995,87 @@ test "std.zon tuples" {
20271995 // Extra field
20281996 {
20291997 const Tuple = struct { f32, bool };
2030 var errors: Errors = .init(arena);
20311998 try std.testing.expectError(
20321999 error.ParseZon,
2033 fromSlice(Tuple, .{
2000 fromSliceNoAlloc(Tuple, .{
20342001 .gpa = gpa,
2002 .arena = arena,
20352003 .source = ".{0.5, true, 123}",
20362004 .errors = &errors,
20372005 }),
20382006 );
20392007 try std.testing.expectFmt(
2008 \\input.zon: error.ParseZon
20402009 \\input.zon:1:14: error: index 2 outside of tuple length 2
20412010 \\
2042 , "{f}", .{errors.fmt("input.zon")});
2011 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
20432012 }
20442013
20452014 // Extra field
20462015 {
20472016 const Tuple = struct { f32, bool };
2048 var errors: Errors = .init(arena);
20492017 try std.testing.expectError(
20502018 error.ParseZon,
2051 fromSlice(Tuple, .{
2019 fromSliceNoAlloc(Tuple, .{
20522020 .gpa = gpa,
2021 .arena = arena,
20532022 .source = ".{0.5}",
20542023 .errors = &errors,
20552024 }),
20562025 );
20572026 try std.testing.expectFmt(
2027 \\input.zon: error.ParseZon
20582028 \\input.zon:1:2: error: missing tuple field with index 1
20592029 \\
2060 , "{f}", .{errors.fmt("input.zon")});
2030 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
20612031 }
20622032
20632033 // Tuple with unexpected field names
20642034 {
20652035 const Tuple = struct { f32 };
2066 var errors: Errors = .init(arena);
20672036 try std.testing.expectError(
20682037 error.ParseZon,
2069 fromSlice(Tuple, .{
2038 fromSliceNoAlloc(Tuple, .{
20702039 .gpa = gpa,
2040 .arena = arena,
20712041 .source = ".{.foo = 10.0}",
20722042 .errors = &errors,
20732043 }),
20742044 );
2075 try std.testing.expectFmt("input.zon:1:2: error: expected tuple\n", "{f}", .{errors.fmt("input.zon")});
2045 try std.testing.expectFmt(
2046 \\input.zon: error.ParseZon
2047 \\input.zon:1:2: error: expected tuple
2048 \\
2049 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
20762050 }
20772051
20782052 // Struct with missing field names
20792053 {
20802054 const Struct = struct { foo: f32 };
2081 var errors: Errors = .init(arena);
20822055 try std.testing.expectError(
20832056 error.ParseZon,
2084 fromSlice(Struct, .{
2057 fromSliceNoAlloc(Struct, .{
20852058 .gpa = gpa,
2059 .arena = arena,
20862060 .source = ".{10.0}",
20872061 .errors = &errors,
20882062 }),
20892063 );
20902064 try std.testing.expectFmt(
2065 \\input.zon: error.ParseZon
20912066 \\input.zon:1:2: error: expected struct
20922067 \\
2093 , "{f}", .{errors.fmt("input.zon")});
2068 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
20942069 }
20952070
20962071 // Comptime field
20972072 {
20982073 const Vec2 = struct { f32, comptime f32 = 1.5 };
2099 const parsed = try fromSlice(Vec2, .{
2074 const parsed = try fromSliceNoAlloc(Vec2, .{
21002075 .gpa = gpa,
2076 .arena = arena,
21012077 .source = ".{ 1.2 }",
2102 .errors = null,
2078 .errors = &errors,
21032079 });
21042080 try std.testing.expectEqual(Vec2{ 1.2, 1.5 }, parsed);
21052081 }
......@@ -2107,17 +2083,18 @@ test "std.zon tuples" {
21072083 // Comptime field assignment
21082084 {
21092085 const Vec2 = struct { f32, comptime f32 = 1.5 };
2110 var errors: Errors = .init(arena);
2111 const parsed = fromSlice(Vec2, .{
2086 const parsed = fromSliceNoAlloc(Vec2, .{
21122087 .gpa = gpa,
2088 .arena = arena,
21132089 .source = ".{ 1.2, 1.5}",
21142090 .errors = &errors,
21152091 });
21162092 try std.testing.expectError(error.ParseZon, parsed);
21172093 try std.testing.expectFmt(
2094 \\input.zon: error.ParseZon
21182095 \\input.zon:1:9: error: cannot initialize comptime field
21192096 \\
2120 , "{f}", .{errors.fmt("input.zon")});
2097 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
21212098 }
21222099}
21232100
......@@ -2129,50 +2106,57 @@ test "std.zon arrays and slices" {
21292106 var arena_allocator: ArenaAllocator = .init(gpa);
21302107 defer arena_allocator.deinit();
21312108 const arena = arena_allocator.allocator();
2109 var errors: Errors = .empty;
21322110
21332111 // Literals
21342112 {
21352113 // Arrays
21362114 {
2137 const zero = try fromSlice([0]u8, .{
2115 const zero = try fromSliceNoAlloc([0]u8, .{
21382116 .gpa = gpa,
2117 .arena = arena,
21392118 .source = ".{}",
2140 .errors = null,
2119 .errors = &errors,
21412120 });
21422121 try std.testing.expectEqualSlices(u8, &@as([0]u8, .{}), &zero);
21432122
2144 const one = try fromSlice([1]u8, .{
2123 const one = try fromSliceNoAlloc([1]u8, .{
21452124 .gpa = gpa,
2125 .arena = arena,
21462126 .source = ".{'a'}",
2147 .errors = null,
2127 .errors = &errors,
21482128 });
21492129 try std.testing.expectEqualSlices(u8, &@as([1]u8, .{'a'}), &one);
21502130
2151 const two = try fromSlice([2]u8, .{
2131 const two = try fromSliceNoAlloc([2]u8, .{
21522132 .gpa = gpa,
2133 .arena = arena,
21532134 .source = ".{'a', 'b'}",
2154 .errors = null,
2135 .errors = &errors,
21552136 });
21562137 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two);
21572138
2158 const two_comma = try fromSlice([2]u8, .{
2139 const two_comma = try fromSliceNoAlloc([2]u8, .{
21592140 .gpa = gpa,
2141 .arena = arena,
21602142 .source = ".{'a', 'b',}",
2161 .errors = null,
2143 .errors = &errors,
21622144 });
21632145 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two_comma);
21642146
2165 const three = try fromSlice([3]u8, .{
2147 const three = try fromSliceNoAlloc([3]u8, .{
21662148 .gpa = gpa,
2149 .arena = arena,
21672150 .source = ".{'a', 'b', 'c'}",
2168 .errors = null,
2151 .errors = &errors,
21692152 });
21702153 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, &three);
21712154
2172 const sentinel = try fromSlice([3:'z']u8, .{
2155 const sentinel = try fromSliceNoAlloc([3:'z']u8, .{
21732156 .gpa = gpa,
2157 .arena = arena,
21742158 .source = ".{'a', 'b', 'c'}",
2175 .errors = null,
2159 .errors = &errors,
21762160 });
21772161 const expected_sentinel: [3:'z']u8 = .{ 'a', 'b', 'c' };
21782162 try std.testing.expectEqualSlices(u8, &expected_sentinel, &sentinel);
......@@ -2180,51 +2164,51 @@ test "std.zon arrays and slices" {
21802164
21812165 // Slice literals
21822166 {
2183 const zero = try fromSliceAlloc([]const u8, .{
2167 const zero = try fromSlice([]const u8, .{
21842168 .gpa = gpa,
21852169 .arena = arena,
21862170 .source = ".{}",
2187 .errors = null,
2171 .errors = &errors,
21882172 });
21892173 try std.testing.expectEqualSlices(u8, @as([]const u8, &.{}), zero);
21902174
2191 const one = try fromSliceAlloc([]u8, .{
2175 const one = try fromSlice([]u8, .{
21922176 .gpa = gpa,
21932177 .arena = arena,
21942178 .source = ".{'a'}",
2195 .errors = null,
2179 .errors = &errors,
21962180 });
21972181 try std.testing.expectEqualSlices(u8, &.{'a'}, one);
21982182
2199 const two = try fromSliceAlloc([]const u8, .{
2183 const two = try fromSlice([]const u8, .{
22002184 .gpa = gpa,
22012185 .arena = arena,
22022186 .source = ".{'a', 'b'}",
2203 .errors = null,
2187 .errors = &errors,
22042188 });
22052189 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two);
22062190
2207 const two_comma = try fromSliceAlloc([]const u8, .{
2191 const two_comma = try fromSlice([]const u8, .{
22082192 .gpa = gpa,
22092193 .arena = arena,
22102194 .source = ".{'a', 'b',}",
2211 .errors = null,
2195 .errors = &errors,
22122196 });
22132197 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two_comma);
22142198
2215 const three = try fromSliceAlloc([]u8, .{
2199 const three = try fromSlice([]u8, .{
22162200 .gpa = gpa,
22172201 .arena = arena,
22182202 .source = ".{'a', 'b', 'c'}",
2219 .errors = null,
2203 .errors = &errors,
22202204 });
22212205 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, three);
22222206
2223 const sentinel = try fromSliceAlloc([:'z']const u8, .{
2207 const sentinel = try fromSlice([:'z']const u8, .{
22242208 .gpa = gpa,
22252209 .arena = arena,
22262210 .source = ".{'a', 'b', 'c'}",
2227 .errors = null,
2211 .errors = &errors,
22282212 });
22292213 const expected_sentinel: [:'z']const u8 = &.{ 'a', 'b', 'c' };
22302214 try std.testing.expectEqualSlices(u8, expected_sentinel, sentinel);
......@@ -2235,11 +2219,11 @@ test "std.zon arrays and slices" {
22352219 {
22362220 // Arrays
22372221 {
2238 const parsed = try fromSliceAlloc([1][]const u8, .{
2222 const parsed = try fromSlice([1][]const u8, .{
22392223 .gpa = gpa,
22402224 .arena = arena,
22412225 .source = ".{\"abc\"}",
2242 .errors = null,
2226 .errors = &errors,
22432227 });
22442228 const expected: [1][]const u8 = .{"abc"};
22452229 try std.testing.expectEqualDeep(expected, parsed);
......@@ -2247,11 +2231,11 @@ test "std.zon arrays and slices" {
22472231
22482232 // Slice literals
22492233 {
2250 const parsed = try fromSliceAlloc([]const []const u8, .{
2234 const parsed = try fromSlice([]const []const u8, .{
22512235 .gpa = gpa,
22522236 .arena = arena,
22532237 .source = ".{\"abc\"}",
2254 .errors = null,
2238 .errors = &errors,
22552239 });
22562240 const expected: []const []const u8 = &.{"abc"};
22572241 try std.testing.expectEqualDeep(expected, parsed);
......@@ -2262,10 +2246,11 @@ test "std.zon arrays and slices" {
22622246 {
22632247 // Arrays
22642248 {
2265 const sentinel = try fromSlice([1:2]u8, .{
2249 const sentinel = try fromSliceNoAlloc([1:2]u8, .{
22662250 .gpa = gpa,
2251 .arena = arena,
22672252 .source = ".{1}",
2268 .errors = null,
2253 .errors = &errors,
22692254 });
22702255 try std.testing.expectEqual(@as(usize, 1), sentinel.len);
22712256 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);
......@@ -2274,11 +2259,11 @@ test "std.zon arrays and slices" {
22742259
22752260 // Slice literals
22762261 {
2277 const sentinel = try fromSliceAlloc([:2]align(4) u8, .{
2262 const sentinel = try fromSlice([:2]align(4) u8, .{
22782263 .gpa = gpa,
22792264 .arena = arena,
22802265 .source = ".{1}",
2281 .errors = null,
2266 .errors = &errors,
22822267 });
22832268 try std.testing.expectEqual(@as(usize, 1), sentinel.len);
22842269 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);
......@@ -2288,101 +2273,112 @@ test "std.zon arrays and slices" {
22882273
22892274 // Expect 0 find 3
22902275 {
2291 var errors: Errors = .init(arena);
22922276 try std.testing.expectError(
22932277 error.ParseZon,
2294 fromSlice([0]u8, .{
2278 fromSliceNoAlloc([0]u8, .{
22952279 .gpa = gpa,
2280 .arena = arena,
22962281 .source = ".{'a', 'b', 'c'}",
22972282 .errors = &errors,
22982283 }),
22992284 );
23002285 try std.testing.expectFmt(
2286 \\input.zon: error.ParseZon
23012287 \\input.zon:1:3: error: index 0 outside of array of length 0
23022288 \\
2303 , "{f}", .{errors.fmt("input.zon")});
2289 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23042290 }
23052291
23062292 // Expect 1 find 2
23072293 {
2308 var errors: Errors = .init(arena);
23092294 try std.testing.expectError(
23102295 error.ParseZon,
2311 fromSlice([1]u8, .{
2296 fromSliceNoAlloc([1]u8, .{
23122297 .gpa = gpa,
2298 .arena = arena,
23132299 .source = ".{'a', 'b'}",
23142300 .errors = &errors,
23152301 }),
23162302 );
23172303 try std.testing.expectFmt(
2304 \\input.zon: error.ParseZon
23182305 \\input.zon:1:8: error: index 1 outside of array of length 1
23192306 \\
2320 , "{f}", .{errors.fmt("input.zon")});
2307 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23212308 }
23222309
23232310 // Expect 2 find 1
23242311 {
2325 var errors: Errors = .init(arena);
23262312 try std.testing.expectError(
23272313 error.ParseZon,
2328 fromSlice([2]u8, .{
2314 fromSliceNoAlloc([2]u8, .{
23292315 .gpa = gpa,
2316 .arena = arena,
23302317 .source = ".{'a'}",
23312318 .errors = &errors,
23322319 }),
23332320 );
23342321 try std.testing.expectFmt(
2322 \\input.zon: error.ParseZon
23352323 \\input.zon:1:2: error: expected 2 array elements; found 1
23362324 \\
2337 , "{f}", .{errors.fmt("input.zon")});
2325 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23382326 }
23392327
23402328 // Expect 3 find 0
23412329 {
2342 var errors: Errors = .init(arena);
23432330 try std.testing.expectError(
23442331 error.ParseZon,
2345 fromSlice([3]u8, .{
2332 fromSliceNoAlloc([3]u8, .{
23462333 .gpa = gpa,
2334 .arena = arena,
23472335 .source = ".{}",
23482336 .errors = &errors,
23492337 }),
23502338 );
2351 try std.testing.expectFmt("input.zon:1:2: error: expected 3 array elements; found 0\n", "{f}", .{errors.fmt("input.zon")});
2339 try std.testing.expectFmt(
2340 \\input.zon: error.ParseZon
2341 \\input.zon:1:2: error: expected 3 array elements; found 0
2342 \\
2343 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23522344 }
23532345
23542346 // Wrong inner type
23552347 {
23562348 // Array
23572349 {
2358 var errors: Errors = .init(arena);
23592350 try std.testing.expectError(
23602351 error.ParseZon,
2361 fromSlice([3]bool, .{
2352 fromSliceNoAlloc([3]bool, .{
23622353 .gpa = gpa,
2354 .arena = arena,
23632355 .source = ".{'a', 'b', 'c'}",
23642356 .errors = &errors,
23652357 }),
23662358 );
23672359 try std.testing.expectFmt(
2360 \\input.zon: error.ParseZon
23682361 \\input.zon:1:3: error: expected type 'bool'
23692362 \\
2370 , "{f}", .{errors.fmt("input.zon")});
2363 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23712364 }
23722365
23732366 // Slice
23742367 {
2375 var errors: Errors = .init(arena);
23762368 try std.testing.expectError(
23772369 error.ParseZon,
2378 fromSliceAlloc([]bool, .{
2370 fromSlice([]bool, .{
23792371 .gpa = gpa,
23802372 .arena = arena,
23812373 .source = ".{'a', 'b', 'c'}",
23822374 .errors = &errors,
23832375 }),
23842376 );
2385 try std.testing.expectFmt("input.zon:1:3: error: expected type 'bool'\n", "{f}", .{errors.fmt("input.zon")});
2377 try std.testing.expectFmt(
2378 \\input.zon: error.ParseZon
2379 \\input.zon:1:3: error: expected type 'bool'
2380 \\
2381 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
23862382 }
23872383 }
23882384
......@@ -2390,43 +2386,47 @@ test "std.zon arrays and slices" {
23902386 {
23912387 // Array
23922388 {
2393 var errors: Errors = .init(arena);
23942389 try std.testing.expectError(
23952390 error.ParseZon,
2396 fromSlice([3]u8, .{
2391 fromSliceNoAlloc([3]u8, .{
23972392 .gpa = gpa,
2393 .arena = arena,
23982394 .source = "'a'",
23992395 .errors = &errors,
24002396 }),
24012397 );
24022398 try std.testing.expectFmt(
2399 \\input.zon: error.ParseZon
24032400 \\input.zon:1:1: error: expected array
24042401 \\
2405 , "{f}", .{errors.fmt("input.zon")});
2402 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
24062403 }
24072404
24082405 // Slice
24092406 {
2410 var errors: Errors = .init(arena);
24112407 try std.testing.expectError(
24122408 error.ParseZon,
2413 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "'a'", .errors = &errors }),
2409 fromSlice([]u8, .{ .gpa = gpa, .arena = arena, .source = "'a'", .errors = &errors }),
24142410 );
2415 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
2411 try std.testing.expectFmt(
2412 \\input.zon: error.ParseZon
2413 \\input.zon:1:1: error: expected array
2414 \\
2415 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
24162416 }
24172417 }
24182418
24192419 // Address of is not allowed (indirection for slices in ZON is implicit)
24202420 {
2421 var errors: Errors = .init(arena);
24222421 try std.testing.expectError(
24232422 error.ParseZon,
2424 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = " &.{'a', 'b', 'c'}", .errors = &errors }),
2423 fromSlice([]u8, .{ .gpa = gpa, .arena = arena, .source = " &.{'a', 'b', 'c'}", .errors = &errors }),
24252424 );
24262425 try std.testing.expectFmt(
2426 \\input.zon: error.ParseZon
24272427 \\input.zon:1:3: error: pointers are not available in ZON
24282428 \\
2429 , "{f}", .{errors.fmt("input.zon")});
2429 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
24302430 }
24312431}
24322432
......@@ -2435,36 +2435,37 @@ test "std.zon string literal" {
24352435 var arena_allocator: ArenaAllocator = .init(gpa);
24362436 defer arena_allocator.deinit();
24372437 const arena = arena_allocator.allocator();
2438 var errors: Errors = .empty;
24382439
24392440 // Basic string literal
24402441 {
2441 const parsed = try fromSliceAlloc([]const u8, .{
2442 const parsed = try fromSlice([]const u8, .{
24422443 .gpa = gpa,
24432444 .arena = arena,
24442445 .source = "\"abc\"",
2445 .errors = null,
2446 .errors = &errors,
24462447 });
24472448 try std.testing.expectEqualStrings(@as([]const u8, "abc"), parsed);
24482449 }
24492450
24502451 // String literal with escape characters
24512452 {
2452 const parsed = try fromSliceAlloc([]const u8, .{
2453 const parsed = try fromSlice([]const u8, .{
24532454 .gpa = gpa,
24542455 .arena = arena,
24552456 .source = "\"ab\\nc\"",
2456 .errors = null,
2457 .errors = &errors,
24572458 });
24582459 try std.testing.expectEqualStrings(@as([]const u8, "ab\nc"), parsed);
24592460 }
24602461
24612462 // String literal with embedded null
24622463 {
2463 const parsed = try fromSliceAlloc([]const u8, .{
2464 const parsed = try fromSlice([]const u8, .{
24642465 .gpa = gpa,
24652466 .arena = arena,
24662467 .source = "\"ab\\x00c\"",
2467 .errors = null,
2468 .errors = &errors,
24682469 });
24692470 try std.testing.expectEqualStrings(@as([]const u8, "ab\x00c"), parsed);
24702471 }
......@@ -2472,24 +2473,27 @@ test "std.zon string literal" {
24722473 // Passing string literal to a mutable slice
24732474 {
24742475 {
2475 var errors: Errors = .init(arena);
24762476 try std.testing.expectError(
24772477 error.ParseZon,
2478 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "\"abcd\"", .errors = &errors }),
2478 fromSlice([]u8, .{ .gpa = gpa, .arena = arena, .source = "\"abcd\"", .errors = &errors }),
24792479 );
2480 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
2480 try std.testing.expectFmt(
2481 \\input.zon: error.ParseZon
2482 \\input.zon:1:1: error: expected array
2483 \\
2484 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
24812485 }
24822486
24832487 {
2484 var errors: Errors = .init(arena);
24852488 try std.testing.expectError(
24862489 error.ParseZon,
2487 fromSliceAlloc([]u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\abcd", .errors = &errors }),
2490 fromSlice([]u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\abcd", .errors = &errors }),
24882491 );
24892492 try std.testing.expectFmt(
2493 \\input.zon: error.ParseZon
24902494 \\input.zon:1:1: error: expected array
24912495 \\
2492 , "{f}", .{errors.fmt("input.zon")});
2496 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
24932497 }
24942498 }
24952499
......@@ -2500,54 +2504,59 @@ test "std.zon string literal" {
25002504 defer ast.deinit(gpa);
25012505 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
25022506 defer zoir.deinit(gpa);
2503 var errors: Errors = .init(arena);
25042507 try std.testing.expectError(
25052508 error.ParseZon,
2506 fromSlice([4:0]u8, .{
2509 fromSliceNoAlloc([4:0]u8, .{
25072510 .gpa = gpa,
2511 .arena = arena,
25082512 .source = "\"abcd\"",
25092513 .errors = &errors,
25102514 }),
25112515 );
2512 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
2516 try std.testing.expectFmt(
2517 \\input.zon: error.ParseZon
2518 \\input.zon:1:1: error: expected array
2519 \\
2520 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
25132521 }
25142522
25152523 {
2516 var errors: Errors = .init(arena);
25172524 try std.testing.expectError(
25182525 error.ParseZon,
2519 fromSlice([4:0]u8, .{
2526 fromSliceNoAlloc([4:0]u8, .{
25202527 .gpa = gpa,
2528 .arena = arena,
25212529 .source = "\\\\abcd",
25222530 .errors = &errors,
25232531 }),
25242532 );
25252533 try std.testing.expectFmt(
2534 \\input.zon: error.ParseZon
25262535 \\input.zon:1:1: error: expected array
25272536 \\
2528 , "{f}", .{errors.fmt("input.zon")});
2537 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
25292538 }
25302539 }
25312540
25322541 // Zero terminated slices
25332542 {
25342543 {
2535 const parsed: [:0]const u8 = try fromSliceAlloc([:0]const u8, .{
2544 const parsed: [:0]const u8 = try fromSlice([:0]const u8, .{
25362545 .gpa = gpa,
25372546 .arena = arena,
25382547 .source = "\"abc\"",
2539 .errors = null,
2548 .errors = &errors,
25402549 });
25412550 try std.testing.expectEqualStrings("abc", parsed);
25422551 try std.testing.expectEqual(@as(u8, 0), parsed[3]);
25432552 }
25442553
25452554 {
2546 const parsed: [:0]const u8 = try fromSliceAlloc([:0]const u8, .{
2555 const parsed: [:0]const u8 = try fromSlice([:0]const u8, .{
25472556 .gpa = gpa,
25482557 .arena = arena,
25492558 .source = "\\\\abc",
2550 .errors = null,
2559 .errors = &errors,
25512560 });
25522561 try std.testing.expectEqualStrings("abc", parsed);
25532562 try std.testing.expectEqual(@as(u8, 0), parsed[3]);
......@@ -2557,114 +2566,119 @@ test "std.zon string literal" {
25572566 // Other value terminated slices
25582567 {
25592568 {
2560 var errors: Errors = .init(arena);
25612569 try std.testing.expectError(
25622570 error.ParseZon,
2563 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\"foo\"", .errors = &errors }),
2571 fromSlice([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\"foo\"", .errors = &errors }),
25642572 );
2565 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
2573 try std.testing.expectFmt(
2574 \\input.zon: error.ParseZon
2575 \\input.zon:1:1: error: expected array
2576 \\
2577 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
25662578 }
25672579
25682580 {
2569 var errors: Errors = .init(arena);
25702581 try std.testing.expectError(
25712582 error.ParseZon,
2572 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\foo", .errors = &errors }),
2583 fromSlice([:1]const u8, .{ .gpa = gpa, .arena = arena, .source = "\\\\foo", .errors = &errors }),
25732584 );
25742585 try std.testing.expectFmt(
2586 \\input.zon: error.ParseZon
25752587 \\input.zon:1:1: error: expected array
25762588 \\
2577 , "{f}", .{errors.fmt("input.zon")});
2589 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
25782590 }
25792591 }
25802592
25812593 // Expecting string literal, getting something else
25822594 {
2583 var errors: Errors = .init(arena);
25842595 try std.testing.expectError(
25852596 error.ParseZon,
2586 fromSliceAlloc([]const u8, .{ .gpa = gpa, .arena = arena, .source = "true", .errors = &errors }),
2597 fromSlice([]const u8, .{ .gpa = gpa, .arena = arena, .source = "true", .errors = &errors }),
25872598 );
25882599 try std.testing.expectFmt(
2600 \\input.zon: error.ParseZon
25892601 \\input.zon:1:1: error: expected string
25902602 \\
2591 , "{f}", .{errors.fmt("input.zon")});
2603 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
25922604 }
25932605
25942606 // Expecting string literal, getting an incompatible tuple
25952607 {
2596 var errors: Errors = .init(arena);
25972608 try std.testing.expectError(
25982609 error.ParseZon,
2599 fromSliceAlloc([]const u8, .{ .gpa = gpa, .arena = arena, .source = ".{false}", .errors = &errors }),
2610 fromSlice([]const u8, .{ .gpa = gpa, .arena = arena, .source = ".{false}", .errors = &errors }),
26002611 );
26012612 try std.testing.expectFmt(
2613 \\input.zon: error.ParseZon
26022614 \\input.zon:1:3: error: expected type 'u8'
26032615 \\
2604 , "{f}", .{errors.fmt("input.zon")});
2616 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26052617 }
26062618
26072619 // Invalid string literal
26082620 {
2609 var errors: Errors = .init(arena);
26102621 try std.testing.expectError(
26112622 error.ParseZon,
2612 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"\\a\"", .errors = &errors }),
2623 fromSlice([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"\\a\"", .errors = &errors }),
26132624 );
26142625 try std.testing.expectFmt(
2626 \\input.zon: error.ParseZon
26152627 \\input.zon:1:3: error: invalid escape character: 'a'
26162628 \\
2617 , "{f}", .{errors.fmt("input.zon")});
2629 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26182630 }
26192631
26202632 // Slice wrong child type
26212633 {
26222634 {
2623 var errors: Errors = .init(arena);
26242635 try std.testing.expectError(
26252636 error.ParseZon,
2626 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"a\"", .errors = &errors }),
2637 fromSlice([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\"a\"", .errors = &errors }),
26272638 );
26282639 try std.testing.expectFmt(
2640 \\input.zon: error.ParseZon
26292641 \\input.zon:1:1: error: expected array
26302642 \\
2631 , "{f}", .{errors.fmt("input.zon")});
2643 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26322644 }
26332645
26342646 {
2635 var errors: Errors = .init(arena);
26362647 try std.testing.expectError(
26372648 error.ParseZon,
2638 fromSliceAlloc([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\\\\a", .errors = &errors }),
2649 fromSlice([]const i8, .{ .gpa = gpa, .arena = arena, .source = "\\\\a", .errors = &errors }),
26392650 );
26402651 try std.testing.expectFmt(
2652 \\input.zon: error.ParseZon
26412653 \\input.zon:1:1: error: expected array
26422654 \\
2643 , "{f}", .{errors.fmt("input.zon")});
2655 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26442656 }
26452657 }
26462658
26472659 // Bad alignment
26482660 {
26492661 {
2650 var errors: Errors = .init(arena);
26512662 try std.testing.expectError(
26522663 error.ParseZon,
2653 fromSliceAlloc([]align(2) const u8, .{
2664 fromSlice([]align(2) const u8, .{
26542665 .gpa = gpa,
26552666 .arena = arena,
26562667 .source = "\"abc\"",
26572668 .errors = &errors,
26582669 }),
26592670 );
2660 try std.testing.expectFmt("input.zon:1:1: error: expected array\n", "{f}", .{errors.fmt("input.zon")});
2671 try std.testing.expectFmt(
2672 \\input.zon: error.ParseZon
2673 \\input.zon:1:1: error: expected array
2674 \\
2675 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26612676 }
26622677
26632678 {
2664 var errors: Errors = .init(arena);
26652679 try std.testing.expectError(
26662680 error.ParseZon,
2667 fromSliceAlloc([]align(2) const u8, .{
2681 fromSlice([]align(2) const u8, .{
26682682 .gpa = gpa,
26692683 .arena = arena,
26702684 .source = "\\\\abc",
......@@ -2672,9 +2686,10 @@ test "std.zon string literal" {
26722686 }),
26732687 );
26742688 try std.testing.expectFmt(
2689 \\input.zon: error.ParseZon
26752690 \\input.zon:1:1: error: expected array
26762691 \\
2677 , "{f}", .{errors.fmt("input.zon")});
2692 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
26782693 }
26792694 }
26802695
......@@ -2687,7 +2702,7 @@ test "std.zon string literal" {
26872702 message2: String,
26882703 message3: String,
26892704 };
2690 const parsed = try fromSliceAlloc(S, .{
2705 const parsed = try fromSlice(S, .{
26912706 .gpa = gpa,
26922707 .arena = arena,
26932708 .source =
......@@ -2708,7 +2723,7 @@ test "std.zon string literal" {
27082723 \\ \\and this.
27092724 \\}
27102725 ,
2711 .errors = null,
2726 .errors = &errors,
27122727 });
27132728 try std.testing.expectEqualStrings(
27142729 "hello, world!\nthis is a multiline string!\n\n...",
......@@ -2725,6 +2740,7 @@ test "std.zon enum literals" {
27252740 var arena_allocator: ArenaAllocator = .init(gpa);
27262741 defer arena_allocator.deinit();
27272742 const arena = arena_allocator.allocator();
2743 var errors: Errors = .empty;
27282744
27292745 const Enum = enum {
27302746 foo,
......@@ -2734,98 +2750,106 @@ test "std.zon enum literals" {
27342750 };
27352751
27362752 // Tags that exist
2737 try std.testing.expectEqual(Enum.foo, try fromSlice(Enum, .{
2753 try std.testing.expectEqual(Enum.foo, try fromSliceNoAlloc(Enum, .{
27382754 .gpa = gpa,
2755 .arena = arena,
27392756 .source = ".foo",
2740 .errors = null,
2757 .errors = &errors,
27412758 }));
2742 try std.testing.expectEqual(Enum.bar, try fromSlice(Enum, .{
2759 try std.testing.expectEqual(Enum.bar, try fromSliceNoAlloc(Enum, .{
27432760 .gpa = gpa,
2761 .arena = arena,
27442762 .source = ".bar",
2745 .errors = null,
2763 .errors = &errors,
27462764 }));
2747 try std.testing.expectEqual(Enum.baz, try fromSlice(Enum, .{
2765 try std.testing.expectEqual(Enum.baz, try fromSliceNoAlloc(Enum, .{
27482766 .gpa = gpa,
2767 .arena = arena,
27492768 .source = ".baz",
2750 .errors = null,
2769 .errors = &errors,
27512770 }));
27522771 try std.testing.expectEqual(
27532772 Enum.@"ab\nc",
2754 try fromSlice(Enum, .{
2773 try fromSliceNoAlloc(Enum, .{
27552774 .gpa = gpa,
2775 .arena = arena,
27562776 .source = ".@\"ab\\nc\"",
2757 .errors = null,
2777 .errors = &errors,
27582778 }),
27592779 );
27602780
27612781 // Bad tag
27622782 {
2763 var errors: Errors = .init(arena);
27642783 try std.testing.expectError(
27652784 error.ParseZon,
2766 fromSlice(Enum, .{
2785 fromSliceNoAlloc(Enum, .{
27672786 .gpa = gpa,
2787 .arena = arena,
27682788 .source = ".qux",
27692789 .errors = &errors,
27702790 }),
27712791 );
27722792 try std.testing.expectFmt(
2793 \\input.zon: error.ParseZon
27732794 \\input.zon:1:2: error: unexpected enum literal 'qux'
27742795 \\input.zon:1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
27752796 \\
2776 , "{f}", .{errors.fmt("input.zon")});
2797 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
27772798 }
27782799
27792800 // Bad tag that's too long for parser
27802801 {
2781 var errors: Errors = .init(arena);
27822802 try std.testing.expectError(
27832803 error.ParseZon,
2784 fromSlice(Enum, .{
2804 fromSliceNoAlloc(Enum, .{
27852805 .gpa = gpa,
2806 .arena = arena,
27862807 .source = ".@\"foobarbaz\"",
27872808 .errors = &errors,
27882809 }),
27892810 );
27902811 try std.testing.expectFmt(
2812 \\input.zon: error.ParseZon
27912813 \\input.zon:1:2: error: unexpected enum literal 'foobarbaz'
27922814 \\input.zon:1:2: note: supported: 'foo', 'bar', 'baz', '@"ab\nc"'
27932815 \\
2794 , "{f}", .{errors.fmt("input.zon")});
2816 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
27952817 }
27962818
27972819 // Bad type
27982820 {
2799 var errors: Errors = .init(arena);
28002821 try std.testing.expectError(
28012822 error.ParseZon,
2802 fromSlice(Enum, .{
2823 fromSliceNoAlloc(Enum, .{
28032824 .gpa = gpa,
2825 .arena = arena,
28042826 .source = "true",
28052827 .errors = &errors,
28062828 }),
28072829 );
28082830 try std.testing.expectFmt(
2831 \\input.zon: error.ParseZon
28092832 \\input.zon:1:1: error: expected enum literal
28102833 \\
2811 , "{f}", .{errors.fmt("input.zon")});
2834 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
28122835 }
28132836
28142837 // Test embedded nulls in an identifier
28152838 {
2816 var errors: Errors = .init(arena);
28172839 try std.testing.expectError(
28182840 error.ParseZon,
2819 fromSlice(Enum, .{
2841 fromSliceNoAlloc(Enum, .{
28202842 .gpa = gpa,
2843 .arena = arena,
28212844 .source = ".@\"\\x00\"",
28222845 .errors = &errors,
28232846 }),
28242847 );
28252848 try std.testing.expectFmt(
2849 \\input.zon: error.ParseZon
28262850 \\input.zon:1:2: error: identifier cannot contain null bytes
28272851 \\
2828 , "{f}", .{errors.fmt("input.zon")});
2852 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
28292853 }
28302854}
28312855
......@@ -2834,48 +2858,53 @@ test "std.zon parse bool" {
28342858 var arena_allocator: ArenaAllocator = .init(gpa);
28352859 defer arena_allocator.deinit();
28362860 const arena = arena_allocator.allocator();
2861 var errors: Errors = .empty;
28372862
28382863 // Correct bools
2839 try std.testing.expectEqual(true, try fromSlice(bool, .{
2864 try std.testing.expectEqual(true, try fromSliceNoAlloc(bool, .{
28402865 .gpa = gpa,
2866 .arena = arena,
28412867 .source = "true",
2842 .errors = null,
2868 .errors = &errors,
28432869 }));
2844 try std.testing.expectEqual(false, try fromSlice(bool, .{
2870 try std.testing.expectEqual(false, try fromSliceNoAlloc(bool, .{
28452871 .gpa = gpa,
2872 .arena = arena,
28462873 .source = "false",
2847 .errors = null,
2874 .errors = &errors,
28482875 }));
28492876
28502877 // Errors
28512878 {
2852 var errors: Errors = .init(arena);
28532879 try std.testing.expectError(
28542880 error.ParseZon,
2855 fromSlice(bool, .{
2881 fromSliceNoAlloc(bool, .{
28562882 .gpa = gpa,
2883 .arena = arena,
28572884 .source = " foo",
28582885 .errors = &errors,
28592886 }),
28602887 );
28612888 try std.testing.expectFmt(
2889 \\input.zon: error.ParseZon
28622890 \\input.zon:1:2: error: invalid expression
28632891 \\input.zon:1:2: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
28642892 \\input.zon:1:2: note: precede identifier with '.' for an enum literal
28652893 \\
2866 , "{f}", .{errors.fmt("input.zon")});
2894 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
28672895 }
28682896 {
2869 var errors: Errors = .init(arena);
2870 try std.testing.expectError(error.ParseZon, fromSlice(bool, .{
2897 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(bool, .{
28712898 .gpa = gpa,
2899 .arena = arena,
28722900 .source = "123",
28732901 .errors = &errors,
28742902 }));
28752903 try std.testing.expectFmt(
2904 \\input.zon: error.ParseZon
28762905 \\input.zon:1:1: error: expected type 'bool'
28772906 \\
2878 , "{f}", .{errors.fmt("input.zon")});
2907 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
28792908 }
28802909}
28812910
......@@ -2906,410 +2935,461 @@ test "std.zon parse int" {
29062935 var arena_allocator: ArenaAllocator = .init(gpa);
29072936 defer arena_allocator.deinit();
29082937 const arena = arena_allocator.allocator();
2938 var errors: Errors = .empty;
29092939
29102940 // Test various numbers and types
2911 try std.testing.expectEqual(@as(u8, 10), try fromSlice(u8, .{
2941 try std.testing.expectEqual(@as(u8, 10), try fromSliceNoAlloc(u8, .{
29122942 .gpa = gpa,
2943 .arena = arena,
29132944 .source = "10",
2914 .errors = null,
2945 .errors = &errors,
29152946 }));
2916 try std.testing.expectEqual(@as(i16, 24), try fromSlice(i16, .{
2947 try std.testing.expectEqual(@as(i16, 24), try fromSliceNoAlloc(i16, .{
29172948 .gpa = gpa,
2949 .arena = arena,
29182950 .source = "24",
2919 .errors = null,
2951 .errors = &errors,
29202952 }));
2921 try std.testing.expectEqual(@as(i14, -4), try fromSlice(i14, .{
2953 try std.testing.expectEqual(@as(i14, -4), try fromSliceNoAlloc(i14, .{
29222954 .gpa = gpa,
2955 .arena = arena,
29232956 .source = "-4",
2924 .errors = null,
2957 .errors = &errors,
29252958 }));
2926 try std.testing.expectEqual(@as(i32, -123), try fromSlice(i32, .{
2959 try std.testing.expectEqual(@as(i32, -123), try fromSliceNoAlloc(i32, .{
29272960 .gpa = gpa,
2961 .arena = arena,
29282962 .source = "-123",
2929 .errors = null,
2963 .errors = &errors,
29302964 }));
29312965
29322966 // Test limits
2933 try std.testing.expectEqual(@as(i8, 127), try fromSlice(i8, .{
2967 try std.testing.expectEqual(@as(i8, 127), try fromSliceNoAlloc(i8, .{
29342968 .gpa = gpa,
2969 .arena = arena,
29352970 .source = "127",
2936 .errors = null,
2971 .errors = &errors,
29372972 }));
2938 try std.testing.expectEqual(@as(i8, -128), try fromSlice(i8, .{
2973 try std.testing.expectEqual(@as(i8, -128), try fromSliceNoAlloc(i8, .{
29392974 .gpa = gpa,
2975 .arena = arena,
29402976 .source = "-128",
2941 .errors = null,
2977 .errors = &errors,
29422978 }));
29432979
29442980 // Test characters
2945 try std.testing.expectEqual(@as(u8, 'a'), try fromSlice(u8, .{
2981 try std.testing.expectEqual(@as(u8, 'a'), try fromSliceNoAlloc(u8, .{
29462982 .gpa = gpa,
2983 .arena = arena,
29472984 .source = "'a'",
2948 .errors = null,
2985 .errors = &errors,
29492986 }));
2950 try std.testing.expectEqual(@as(u8, 'z'), try fromSlice(u8, .{
2987 try std.testing.expectEqual(@as(u8, 'z'), try fromSliceNoAlloc(u8, .{
29512988 .gpa = gpa,
2989 .arena = arena,
29522990 .source = "'z'",
2953 .errors = null,
2991 .errors = &errors,
29542992 }));
29552993
29562994 // Test big integers
29572995 try std.testing.expectEqual(
29582996 @as(u65, 36893488147419103231),
2959 try fromSlice(u65, .{
2997 try fromSliceNoAlloc(u65, .{
29602998 .gpa = gpa,
2999 .arena = arena,
29613000 .source = "36893488147419103231",
2962 .errors = null,
3001 .errors = &errors,
29633002 }),
29643003 );
29653004 try std.testing.expectEqual(
29663005 @as(u65, 36893488147419103231),
2967 try fromSlice(u65, .{
3006 try fromSliceNoAlloc(u65, .{
29683007 .gpa = gpa,
3008 .arena = arena,
29693009 .source = "368934_881_474191032_31",
2970 .errors = null,
3010 .errors = &errors,
29713011 }),
29723012 );
29733013 try std.testing.expectEqual(
29743014 @as(u128, 340282366920938463463374607431768211455),
2975 try fromSlice(u128, .{
3015 try fromSliceNoAlloc(u128, .{
29763016 .gpa = gpa,
3017 .arena = arena,
29773018 .source = "340282366920938463463374607431768211455",
2978 .errors = null,
3019 .errors = &errors,
29793020 }),
29803021 );
29813022
29823023 // Test big integer limits
29833024 try std.testing.expectEqual(
29843025 @as(i66, 36893488147419103231),
2985 try fromSlice(i66, .{
3026 try fromSliceNoAlloc(i66, .{
29863027 .gpa = gpa,
3028 .arena = arena,
29873029 .source = "36893488147419103231",
2988 .errors = null,
3030 .errors = &errors,
29893031 }),
29903032 );
29913033 try std.testing.expectEqual(
29923034 @as(i66, -36893488147419103232),
2993 try fromSlice(i66, .{
3035 try fromSliceNoAlloc(i66, .{
29943036 .gpa = gpa,
3037 .arena = arena,
29953038 .source = "-36893488147419103232",
2996 .errors = null,
3039 .errors = &errors,
29973040 }),
29983041 );
29993042 {
3000 var errors: Errors = .init(arena);
3001 try std.testing.expectError(error.ParseZon, fromSlice(i66, .{
3043 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i66, .{
30023044 .gpa = gpa,
3045 .arena = arena,
30033046 .source = "36893488147419103232",
30043047 .errors = &errors,
30053048 }));
30063049 try std.testing.expectFmt(
3050 \\input.zon: error.ParseZon
30073051 \\input.zon:1:1: error: type 'i66' cannot represent value
30083052 \\
3009 , "{f}", .{errors.fmt("input.zon")});
3053 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
30103054 }
30113055 {
3012 var errors: Errors = .init(arena);
3013 try std.testing.expectError(error.ParseZon, fromSlice(i66, .{
3056 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i66, .{
30143057 .gpa = gpa,
3058 .arena = arena,
30153059 .source = "-36893488147419103233",
30163060 .errors = &errors,
30173061 }));
30183062 try std.testing.expectFmt(
3063 \\input.zon: error.ParseZon
30193064 \\input.zon:1:1: error: type 'i66' cannot represent value
30203065 \\
3021 , "{f}", .{errors.fmt("input.zon")});
3066 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
30223067 }
30233068
30243069 // Test parsing whole number floats as integers
3025 try std.testing.expectEqual(@as(i8, -1), try fromSlice(i8, .{
3070 try std.testing.expectEqual(@as(i8, -1), try fromSliceNoAlloc(i8, .{
30263071 .gpa = gpa,
3072 .arena = arena,
30273073 .source = "-1.0",
3028 .errors = null,
3074 .errors = &errors,
30293075 }));
3030 try std.testing.expectEqual(@as(i8, 123), try fromSlice(i8, .{
3076 try std.testing.expectEqual(@as(i8, 123), try fromSliceNoAlloc(i8, .{
30313077 .gpa = gpa,
3078 .arena = arena,
30323079 .source = "123.0",
3033 .errors = null,
3080 .errors = &errors,
30343081 }));
30353082
30363083 // Test non-decimal integers
3037 try std.testing.expectEqual(@as(i16, 0xff), try fromSlice(i16, .{
3084 try std.testing.expectEqual(@as(i16, 0xff), try fromSliceNoAlloc(i16, .{
30383085 .gpa = gpa,
3086 .arena = arena,
30393087 .source = "0xff",
3040 .errors = null,
3088 .errors = &errors,
30413089 }));
3042 try std.testing.expectEqual(@as(i16, -0xff), try fromSlice(i16, .{
3090 try std.testing.expectEqual(@as(i16, -0xff), try fromSliceNoAlloc(i16, .{
30433091 .gpa = gpa,
3092 .arena = arena,
30443093 .source = "-0xff",
3045 .errors = null,
3094 .errors = &errors,
30463095 }));
3047 try std.testing.expectEqual(@as(i16, 0o77), try fromSlice(i16, .{
3096 try std.testing.expectEqual(@as(i16, 0o77), try fromSliceNoAlloc(i16, .{
30483097 .gpa = gpa,
3098 .arena = arena,
30493099 .source = "0o77",
3050 .errors = null,
3100 .errors = &errors,
30513101 }));
3052 try std.testing.expectEqual(@as(i16, -0o77), try fromSlice(i16, .{
3102 try std.testing.expectEqual(@as(i16, -0o77), try fromSliceNoAlloc(i16, .{
30533103 .gpa = gpa,
3104 .arena = arena,
30543105 .source = "-0o77",
3055 .errors = null,
3106 .errors = &errors,
30563107 }));
3057 try std.testing.expectEqual(@as(i16, 0b11), try fromSlice(i16, .{
3108 try std.testing.expectEqual(@as(i16, 0b11), try fromSliceNoAlloc(i16, .{
30583109 .gpa = gpa,
3110 .arena = arena,
30593111 .source = "0b11",
3060 .errors = null,
3112 .errors = &errors,
30613113 }));
3062 try std.testing.expectEqual(@as(i16, -0b11), try fromSlice(i16, .{
3114 try std.testing.expectEqual(@as(i16, -0b11), try fromSliceNoAlloc(i16, .{
30633115 .gpa = gpa,
3116 .arena = arena,
30643117 .source = "-0b11",
3065 .errors = null,
3118 .errors = &errors,
30663119 }));
30673120
30683121 // Test non-decimal big integers
3069 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
3122 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSliceNoAlloc(u65, .{
30703123 .gpa = gpa,
3124 .arena = arena,
30713125 .source = "0x1ffffffffffffffff",
3072 .errors = null,
3126 .errors = &errors,
30733127 }));
3074 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
3128 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
30753129 .gpa = gpa,
3130 .arena = arena,
30763131 .source = "0x1ffffffffffffffff",
3077 .errors = null,
3132 .errors = &errors,
30783133 }));
3079 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
3134 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
30803135 .gpa = gpa,
3136 .arena = arena,
30813137 .source = "-0x1ffffffffffffffff",
3082 .errors = null,
3138 .errors = &errors,
30833139 }));
3084 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
3140 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSliceNoAlloc(u65, .{
30853141 .gpa = gpa,
3142 .arena = arena,
30863143 .source = "0o3777777777777777777777",
3087 .errors = null,
3144 .errors = &errors,
30883145 }));
3089 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
3146 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
30903147 .gpa = gpa,
3148 .arena = arena,
30913149 .source = "0o3777777777777777777777",
3092 .errors = null,
3150 .errors = &errors,
30933151 }));
3094 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
3152 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
30953153 .gpa = gpa,
3154 .arena = arena,
30963155 .source = "-0o3777777777777777777777",
3097 .errors = null,
3156 .errors = &errors,
30983157 }));
3099 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
3158 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSliceNoAlloc(u65, .{
31003159 .gpa = gpa,
3160 .arena = arena,
31013161 .source = "0b11111111111111111111111111111111111111111111111111111111111111111",
3102 .errors = null,
3162 .errors = &errors,
31033163 }));
3104 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
3164 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
31053165 .gpa = gpa,
3166 .arena = arena,
31063167 .source = "0b11111111111111111111111111111111111111111111111111111111111111111",
3107 .errors = null,
3168 .errors = &errors,
31083169 }));
3109 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
3170 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSliceNoAlloc(i66, .{
31103171 .gpa = gpa,
3172 .arena = arena,
31113173 .source = "-0b11111111111111111111111111111111111111111111111111111111111111111",
3112 .errors = null,
3174 .errors = &errors,
31133175 }));
31143176
31153177 // Number with invalid character in the middle
31163178 {
3117 var errors: Errors = .init(arena);
3118 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3179 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
31193180 .gpa = gpa,
3181 .arena = arena,
31203182 .source = "32a32",
31213183 .errors = &errors,
31223184 }));
31233185 try std.testing.expectFmt(
3186 \\input.zon: error.ParseZon
31243187 \\input.zon:1:3: error: invalid digit 'a' for decimal base
31253188 \\
3126 , "{f}", .{errors.fmt("input.zon")});
3189 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31273190 }
31283191
31293192 // Failing to parse as int
31303193 {
3131 var errors: Errors = .init(arena);
3132 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3194 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
31333195 .gpa = gpa,
3196 .arena = arena,
31343197 .source = "true",
31353198 .errors = &errors,
31363199 }));
31373200 try std.testing.expectFmt(
3201 \\input.zon: error.ParseZon
31383202 \\input.zon:1:1: error: expected type 'u8'
31393203 \\
3140 , "{f}", .{errors.fmt("input.zon")});
3204 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31413205 }
31423206
31433207 // Failing because an int is out of range
31443208 {
3145 var errors: Errors = .init(arena);
3146 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3209 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
31473210 .gpa = gpa,
3211 .arena = arena,
31483212 .source = "256",
31493213 .errors = &errors,
31503214 }));
31513215 try std.testing.expectFmt(
3216 \\input.zon: error.ParseZon
31523217 \\input.zon:1:1: error: type 'u8' cannot represent value
31533218 \\
3154 , "{f}", .{errors.fmt("input.zon")});
3219 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31553220 }
31563221
31573222 // Failing because a negative int is out of range
31583223 {
3159 var errors: Errors = .init(arena);
3160 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3224 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
31613225 .gpa = gpa,
3226 .arena = arena,
31623227 .source = "-129",
31633228 .errors = &errors,
31643229 }));
31653230 try std.testing.expectFmt(
3231 \\input.zon: error.ParseZon
31663232 \\input.zon:1:1: error: type 'i8' cannot represent value
31673233 \\
3168 , "{f}", .{errors.fmt("input.zon")});
3234 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31693235 }
31703236
31713237 // Failing because an unsigned int is negative
31723238 {
3173 var errors: Errors = .init(arena);
3174 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3239 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
31753240 .gpa = gpa,
3241 .arena = arena,
31763242 .source = "-1",
31773243 .errors = &errors,
31783244 }));
31793245 try std.testing.expectFmt(
3246 \\input.zon: error.ParseZon
31803247 \\input.zon:1:1: error: type 'u8' cannot represent value
31813248 \\
3182 , "{f}", .{errors.fmt("input.zon")});
3249 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31833250 }
31843251
31853252 // Failing because a float is non-whole
31863253 {
3187 var errors: Errors = .init(arena);
3188 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3254 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
31893255 .gpa = gpa,
3256 .arena = arena,
31903257 .source = "1.5",
31913258 .errors = &errors,
31923259 }));
31933260 try std.testing.expectFmt(
3261 \\input.zon: error.ParseZon
31943262 \\input.zon:1:1: error: type 'u8' cannot represent value
31953263 \\
3196 , "{f}", .{errors.fmt("input.zon")});
3264 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
31973265 }
31983266
31993267 // Failing because a float is negative
32003268 {
3201 var errors: Errors = .init(arena);
3202 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3269 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
32033270 .gpa = gpa,
3271 .arena = arena,
32043272 .source = "-1.0",
32053273 .errors = &errors,
32063274 }));
32073275 try std.testing.expectFmt(
3276 \\input.zon: error.ParseZon
32083277 \\input.zon:1:1: error: type 'u8' cannot represent value
32093278 \\
3210 , "{f}", .{errors.fmt("input.zon")});
3279 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32113280 }
32123281
32133282 // Negative integer zero
32143283 {
3215 var errors: Errors = .init(arena);
3216 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3284 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
32173285 .gpa = gpa,
3286 .arena = arena,
32183287 .source = "-0",
32193288 .errors = &errors,
32203289 }));
32213290 try std.testing.expectFmt(
3291 \\input.zon: error.ParseZon
32223292 \\input.zon:1:2: error: integer literal '-0' is ambiguous
32233293 \\input.zon:1:2: note: use '0' for an integer zero
32243294 \\input.zon:1:2: note: use '-0.0' for a floating-point signed zero
32253295 \\
3226 , "{f}", .{errors.fmt("input.zon")});
3296 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32273297 }
32283298
32293299 // Negative integer zero casted to float
32303300 {
3231 var errors: Errors = .init(arena);
3232 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3301 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(f32, .{
32333302 .gpa = gpa,
3303 .arena = arena,
32343304 .source = "-0",
32353305 .errors = &errors,
32363306 }));
32373307 try std.testing.expectFmt(
3308 \\input.zon: error.ParseZon
32383309 \\input.zon:1:2: error: integer literal '-0' is ambiguous
32393310 \\input.zon:1:2: note: use '0' for an integer zero
32403311 \\input.zon:1:2: note: use '-0.0' for a floating-point signed zero
32413312 \\
3242 , "{f}", .{errors.fmt("input.zon")});
3313 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32433314 }
32443315
32453316 // Negative float 0 is allowed
32463317 try std.testing.expect(
3247 std.math.isNegativeZero(try fromSlice(f32, .{
3318 std.math.isNegativeZero(try fromSliceNoAlloc(f32, .{
32483319 .gpa = gpa,
3320 .arena = arena,
32493321 .source = "-0.0",
3250 .errors = null,
3322 .errors = &errors,
32513323 })),
32523324 );
3253 try std.testing.expect(std.math.isPositiveZero(try fromSlice(f32, .{
3325 try std.testing.expect(std.math.isPositiveZero(try fromSliceNoAlloc(f32, .{
32543326 .gpa = gpa,
3327 .arena = arena,
32553328 .source = "0.0",
3256 .errors = null,
3329 .errors = &errors,
32573330 })));
32583331
32593332 // Double negation is not allowed
32603333 {
3261 var errors: Errors = .init(arena);
3262 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3334 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
32633335 .gpa = gpa,
3336 .arena = arena,
32643337 .source = "--2",
32653338 .errors = &errors,
32663339 }));
3267 try std.testing.expectFmt("input.zon:1:1: error: expected number or 'inf' after '-'\n", "{f}", .{errors.fmt("input.zon")});
3340 try std.testing.expectFmt(
3341 \\input.zon: error.ParseZon
3342 \\input.zon:1:1: error: expected number or 'inf' after '-'
3343 \\
3344 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32683345 }
32693346
32703347 {
3271 var errors: Errors = .init(arena);
32723348 try std.testing.expectError(
32733349 error.ParseZon,
3274 fromSlice(f32, .{
3350 fromSliceNoAlloc(f32, .{
32753351 .gpa = gpa,
3352 .arena = arena,
32763353 .source = "--2.0",
32773354 .errors = &errors,
32783355 }),
32793356 );
32803357 try std.testing.expectFmt(
3358 \\input.zon: error.ParseZon
32813359 \\input.zon:1:1: error: expected number or 'inf' after '-'
32823360 \\
3283 , "{f}", .{errors.fmt("input.zon")});
3361 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32843362 }
32853363
32863364 // Invalid int literal
32873365 {
3288 var errors: Errors = .init(arena);
3289 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3366 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
32903367 .gpa = gpa,
3368 .arena = arena,
32913369 .source = "0xg",
32923370 .errors = &errors,
32933371 }));
32943372 try std.testing.expectFmt(
3373 \\input.zon: error.ParseZon
32953374 \\input.zon:1:3: error: invalid digit 'g' for hex base
32963375 \\
3297 , "{f}", .{errors.fmt("input.zon")});
3376 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
32983377 }
32993378
33003379 // Notes on invalid int literal
33013380 {
3302 var errors: Errors = .init(arena);
3303 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3381 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(u8, .{
33043382 .gpa = gpa,
3383 .arena = arena,
33053384 .source = "0123",
33063385 .errors = &errors,
33073386 }));
33083387 try std.testing.expectFmt(
3388 \\input.zon: error.ParseZon
33093389 \\input.zon:1:1: error: number '0123' has leading zero
33103390 \\input.zon:1:1: note: use '0o' prefix for octal literals
33113391 \\
3312 , "{f}", .{errors.fmt("input.zon")});
3392 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
33133393 }
33143394}
33153395
......@@ -3318,30 +3398,33 @@ test "std.zon negative char" {
33183398 var arena_allocator: ArenaAllocator = .init(gpa);
33193399 defer arena_allocator.deinit();
33203400 const arena = arena_allocator.allocator();
3401 var errors: Errors = .empty;
33213402
33223403 {
3323 var errors: Errors = .init(arena);
3324 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3404 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(f32, .{
33253405 .gpa = gpa,
3406 .arena = arena,
33263407 .source = "-'a'",
33273408 .errors = &errors,
33283409 }));
33293410 try std.testing.expectFmt(
3411 \\input.zon: error.ParseZon
33303412 \\input.zon:1:1: error: expected number or 'inf' after '-'
33313413 \\
3332 , "{f}", .{errors.fmt("input.zon")});
3414 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
33333415 }
33343416 {
3335 var errors: Errors = .init(arena);
3336 try std.testing.expectError(error.ParseZon, fromSlice(i16, .{
3417 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i16, .{
33373418 .gpa = gpa,
3419 .arena = arena,
33383420 .source = "-'a'",
33393421 .errors = &errors,
33403422 }));
33413423 try std.testing.expectFmt(
3424 \\input.zon: error.ParseZon
33423425 \\input.zon:1:1: error: expected number or 'inf' after '-'
33433426 \\
3344 , "{f}", .{errors.fmt("input.zon")});
3427 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
33453428 }
33463429}
33473430
......@@ -3352,261 +3435,294 @@ test "std.zon parse float" {
33523435 var arena_allocator: ArenaAllocator = .init(gpa);
33533436 defer arena_allocator.deinit();
33543437 const arena = arena_allocator.allocator();
3438 var errors: Errors = .empty;
33553439
33563440 // Test decimals
3357 try std.testing.expectEqual(@as(f16, 0.5), try fromSlice(f16, .{
3441 try std.testing.expectEqual(@as(f16, 0.5), try fromSliceNoAlloc(f16, .{
33583442 .gpa = gpa,
3443 .arena = arena,
33593444 .source = "0.5",
3360 .errors = null,
3445 .errors = &errors,
33613446 }));
33623447 try std.testing.expectEqual(
33633448 @as(f32, 123.456),
3364 try fromSlice(f32, .{
3449 try fromSliceNoAlloc(f32, .{
33653450 .gpa = gpa,
3451 .arena = arena,
33663452 .source = "123.456",
3367 .errors = null,
3453 .errors = &errors,
33683454 }),
33693455 );
33703456 try std.testing.expectEqual(
33713457 @as(f64, -123.456),
3372 try fromSlice(f64, .{
3458 try fromSliceNoAlloc(f64, .{
33733459 .gpa = gpa,
3460 .arena = arena,
33743461 .source = "-123.456",
3375 .errors = null,
3462 .errors = &errors,
33763463 }),
33773464 );
3378 try std.testing.expectEqual(@as(f128, 42.5), try fromSlice(f128, .{
3465 try std.testing.expectEqual(@as(f128, 42.5), try fromSliceNoAlloc(f128, .{
33793466 .gpa = gpa,
3467 .arena = arena,
33803468 .source = "42.5",
3381 .errors = null,
3469 .errors = &errors,
33823470 }));
33833471
33843472 // Test whole numbers with and without decimals
3385 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, .{
3473 try std.testing.expectEqual(@as(f16, 5.0), try fromSliceNoAlloc(f16, .{
33863474 .gpa = gpa,
3475 .arena = arena,
33873476 .source = "5.0",
3388 .errors = null,
3477 .errors = &errors,
33893478 }));
3390 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, .{
3479 try std.testing.expectEqual(@as(f16, 5.0), try fromSliceNoAlloc(f16, .{
33913480 .gpa = gpa,
3481 .arena = arena,
33923482 .source = "5",
3393 .errors = null,
3483 .errors = &errors,
33943484 }));
3395 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, .{
3485 try std.testing.expectEqual(@as(f32, -102), try fromSliceNoAlloc(f32, .{
33963486 .gpa = gpa,
3487 .arena = arena,
33973488 .source = "-102.0",
3398 .errors = null,
3489 .errors = &errors,
33993490 }));
3400 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, .{
3491 try std.testing.expectEqual(@as(f32, -102), try fromSliceNoAlloc(f32, .{
34013492 .gpa = gpa,
3493 .arena = arena,
34023494 .source = "-102",
3403 .errors = null,
3495 .errors = &errors,
34043496 }));
34053497
34063498 // Test characters and negated characters
3407 try std.testing.expectEqual(@as(f32, 'a'), try fromSlice(f32, .{
3499 try std.testing.expectEqual(@as(f32, 'a'), try fromSliceNoAlloc(f32, .{
34083500 .gpa = gpa,
3501 .arena = arena,
34093502 .source = "'a'",
3410 .errors = null,
3503 .errors = &errors,
34113504 }));
3412 try std.testing.expectEqual(@as(f32, 'z'), try fromSlice(f32, .{
3505 try std.testing.expectEqual(@as(f32, 'z'), try fromSliceNoAlloc(f32, .{
34133506 .gpa = gpa,
3507 .arena = arena,
34143508 .source = "'z'",
3415 .errors = null,
3509 .errors = &errors,
34163510 }));
34173511
34183512 // Test big integers
34193513 try std.testing.expectEqual(
34203514 @as(f32, 36893488147419103231.0),
3421 try fromSlice(f32, .{
3515 try fromSliceNoAlloc(f32, .{
34223516 .gpa = gpa,
3517 .arena = arena,
34233518 .source = "36893488147419103231",
3424 .errors = null,
3519 .errors = &errors,
34253520 }),
34263521 );
34273522 try std.testing.expectEqual(
34283523 @as(f32, -36893488147419103231.0),
3429 try fromSlice(f32, .{
3524 try fromSliceNoAlloc(f32, .{
34303525 .gpa = gpa,
3526 .arena = arena,
34313527 .source = "-36893488147419103231",
3432 .errors = null,
3528 .errors = &errors,
34333529 }),
34343530 );
3435 try std.testing.expectEqual(@as(f128, 0x1ffffffffffffffff), try fromSlice(f128, .{
3531 try std.testing.expectEqual(@as(f128, 0x1ffffffffffffffff), try fromSliceNoAlloc(f128, .{
34363532 .gpa = gpa,
3533 .arena = arena,
34373534 .source = "0x1ffffffffffffffff",
3438 .errors = null,
3535 .errors = &errors,
34393536 }));
3440 try std.testing.expectEqual(@as(f32, @floatFromInt(0x1ffffffffffffffff)), try fromSlice(f32, .{
3537 try std.testing.expectEqual(@as(f32, @floatFromInt(0x1ffffffffffffffff)), try fromSliceNoAlloc(f32, .{
34413538 .gpa = gpa,
3539 .arena = arena,
34423540 .source = "0x1ffffffffffffffff",
3443 .errors = null,
3541 .errors = &errors,
34443542 }));
34453543
34463544 // Exponents, underscores
34473545 try std.testing.expectEqual(
34483546 @as(f32, 123.0E+77),
3449 try fromSlice(f32, .{
3547 try fromSliceNoAlloc(f32, .{
34503548 .gpa = gpa,
3549 .arena = arena,
34513550 .source = "12_3.0E+77",
3452 .errors = null,
3551 .errors = &errors,
34533552 }),
34543553 );
34553554
34563555 // Hexadecimal
34573556 try std.testing.expectEqual(
34583557 @as(f32, 0x103.70p-5),
3459 try fromSlice(f32, .{
3558 try fromSliceNoAlloc(f32, .{
34603559 .gpa = gpa,
3560 .arena = arena,
34613561 .source = "0x103.70p-5",
3462 .errors = null,
3562 .errors = &errors,
34633563 }),
34643564 );
34653565 try std.testing.expectEqual(
34663566 @as(f32, -0x103.70),
3467 try fromSlice(f32, .{
3567 try fromSliceNoAlloc(f32, .{
34683568 .gpa = gpa,
3569 .arena = arena,
34693570 .source = "-0x103.70",
3470 .errors = null,
3571 .errors = &errors,
34713572 }),
34723573 );
34733574 try std.testing.expectEqual(
34743575 @as(f32, 0x1234_5678.9ABC_CDEFp-10),
3475 try fromSlice(f32, .{
3576 try fromSliceNoAlloc(f32, .{
34763577 .gpa = gpa,
3578 .arena = arena,
34773579 .source = "0x1234_5678.9ABC_CDEFp-10",
3478 .errors = null,
3580 .errors = &errors,
34793581 }),
34803582 );
34813583
34823584 // inf, nan
3483 try std.testing.expect(std.math.isPositiveInf(try fromSlice(f32, .{
3585 try std.testing.expect(std.math.isPositiveInf(try fromSliceNoAlloc(f32, .{
34843586 .gpa = gpa,
3587 .arena = arena,
34853588 .source = "inf",
3486 .errors = null,
3589 .errors = &errors,
34873590 })));
3488 try std.testing.expect(std.math.isNegativeInf(try fromSlice(f32, .{
3591 try std.testing.expect(std.math.isNegativeInf(try fromSliceNoAlloc(f32, .{
34893592 .gpa = gpa,
3593 .arena = arena,
34903594 .source = "-inf",
3491 .errors = null,
3595 .errors = &errors,
34923596 })));
3493 try std.testing.expect(std.math.isNan(try fromSlice(f32, .{
3597 try std.testing.expect(std.math.isNan(try fromSliceNoAlloc(f32, .{
34943598 .gpa = gpa,
3599 .arena = arena,
34953600 .source = "nan",
3496 .errors = null,
3601 .errors = &errors,
34973602 })));
34983603
34993604 // Negative nan not allowed
35003605 {
3501 var errors: Errors = .init(arena);
3502 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3606 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(f32, .{
35033607 .gpa = gpa,
3608 .arena = arena,
35043609 .source = "-nan",
35053610 .errors = &errors,
35063611 }));
3507 try std.testing.expectFmt("input.zon:1:1: error: expected number or 'inf' after '-'\n", "{f}", .{errors.fmt("input.zon")});
3612 try std.testing.expectFmt(
3613 \\input.zon: error.ParseZon
3614 \\input.zon:1:1: error: expected number or 'inf' after '-'
3615 \\
3616 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35083617 }
35093618
35103619 // nan as int not allowed
35113620 {
3512 var errors: Errors = .init(arena);
3513 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3621 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
35143622 .gpa = gpa,
3623 .arena = arena,
35153624 .source = "nan",
35163625 .errors = &errors,
35173626 }));
35183627 try std.testing.expectFmt(
3628 \\input.zon: error.ParseZon
35193629 \\input.zon:1:1: error: expected type 'i8'
35203630 \\
3521 , "{f}", .{errors.fmt("input.zon")});
3631 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35223632 }
35233633
35243634 // nan as int not allowed
35253635 {
3526 var errors: Errors = .init(arena);
3527 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3636 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
35283637 .gpa = gpa,
3638 .arena = arena,
35293639 .source = "nan",
35303640 .errors = &errors,
35313641 }));
35323642 try std.testing.expectFmt(
3643 \\input.zon: error.ParseZon
35333644 \\input.zon:1:1: error: expected type 'i8'
35343645 \\
3535 , "{f}", .{errors.fmt("input.zon")});
3646 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35363647 }
35373648
35383649 // inf as int not allowed
35393650 {
3540 var errors: Errors = .init(arena);
3541 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3651 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
35423652 .gpa = gpa,
3653 .arena = arena,
35433654 .source = "inf",
35443655 .errors = &errors,
35453656 }));
35463657 try std.testing.expectFmt(
3658 \\input.zon: error.ParseZon
35473659 \\input.zon:1:1: error: expected type 'i8'
35483660 \\
3549 , "{f}", .{errors.fmt("input.zon")});
3661 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35503662 }
35513663
35523664 // -inf as int not allowed
35533665 {
3554 var errors: Errors = .init(arena);
3555 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3666 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(i8, .{
35563667 .gpa = gpa,
3668 .arena = arena,
35573669 .source = "-inf",
35583670 .errors = &errors,
35593671 }));
35603672 try std.testing.expectFmt(
3673 \\input.zon: error.ParseZon
35613674 \\input.zon:1:1: error: expected type 'i8'
35623675 \\
3563 , "{f}", .{errors.fmt("input.zon")});
3676 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35643677 }
35653678
35663679 // Bad identifier as float
35673680 {
3568 var errors: Errors = .init(arena);
3569 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3681 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(f32, .{
35703682 .gpa = gpa,
3683 .arena = arena,
35713684 .source = "foo",
35723685 .errors = &errors,
35733686 }));
35743687 try std.testing.expectFmt(
3688 \\input.zon: error.ParseZon
35753689 \\input.zon:1:1: error: invalid expression
35763690 \\input.zon:1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
35773691 \\input.zon:1:1: note: precede identifier with '.' for an enum literal
35783692 \\
3579 , "{f}", .{errors.fmt("input.zon")});
3693 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35803694 }
35813695
35823696 {
3583 var errors: Errors = .init(arena);
3584 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3697 try std.testing.expectError(error.ParseZon, fromSliceNoAlloc(f32, .{
35853698 .gpa = gpa,
3699 .arena = arena,
35863700 .source = "-foo",
35873701 .errors = &errors,
35883702 }));
35893703 try std.testing.expectFmt(
3704 \\input.zon: error.ParseZon
35903705 \\input.zon:1:1: error: expected number or 'inf' after '-'
35913706 \\
3592 , "{f}", .{errors.fmt("input.zon")});
3707 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
35933708 }
35943709
35953710 // Non float as float
35963711 {
3597 var errors: Errors = .init(arena);
35983712 try std.testing.expectError(
35993713 error.ParseZon,
3600 fromSlice(f32, .{
3714 fromSliceNoAlloc(f32, .{
36013715 .gpa = gpa,
3716 .arena = arena,
36023717 .source = "\"foo\"",
36033718 .errors = &errors,
36043719 }),
36053720 );
36063721 try std.testing.expectFmt(
3722 \\input.zon: error.ParseZon
36073723 \\input.zon:1:1: error: expected type 'f32'
36083724 \\
3609 , "{f}", .{errors.fmt("input.zon")});
3725 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
36103726 }
36113727}
36123728
......@@ -3615,6 +3731,7 @@ test "std.zon free on error" {
36153731 var arena_allocator: ArenaAllocator = .init(gpa);
36163732 defer arena_allocator.deinit();
36173733 const arena = arena_allocator.allocator();
3734 var errors: Errors = .empty;
36183735
36193736 // Test freeing partially allocated structs
36203737 {
......@@ -3623,7 +3740,7 @@ test "std.zon free on error" {
36233740 y: []const u8,
36243741 z: bool,
36253742 };
3626 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3743 try std.testing.expectError(error.ParseZon, fromSlice(Struct, .{
36273744 .gpa = gpa,
36283745 .arena = arena,
36293746 .source =
......@@ -3633,7 +3750,7 @@ test "std.zon free on error" {
36333750 \\ .z = "fail",
36343751 \\}
36353752 ,
3636 .errors = null,
3753 .errors = &errors,
36373754 }));
36383755 }
36393756
......@@ -3644,7 +3761,7 @@ test "std.zon free on error" {
36443761 []const u8,
36453762 bool,
36463763 };
3647 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3764 try std.testing.expectError(error.ParseZon, fromSlice(Struct, .{
36483765 .gpa = gpa,
36493766 .arena = arena,
36503767 .source =
......@@ -3654,7 +3771,7 @@ test "std.zon free on error" {
36543771 \\ "fail",
36553772 \\}
36563773 ,
3657 .errors = null,
3774 .errors = &errors,
36583775 }));
36593776 }
36603777
......@@ -3663,7 +3780,7 @@ test "std.zon free on error" {
36633780 x: []const u8,
36643781 y: bool,
36653782 };
3666 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3783 try std.testing.expectError(error.ParseZon, fromSlice(Struct, .{
36673784 .gpa = gpa,
36683785 .arena = arena,
36693786 .source =
......@@ -3671,11 +3788,11 @@ test "std.zon free on error" {
36713788 \\ .x = "hello",
36723789 \\}
36733790 ,
3674 .errors = null,
3791 .errors = &errors,
36753792 }));
36763793
36773794 // Test freeing partially allocated arrays
3678 try std.testing.expectError(error.ParseZon, fromSliceAlloc([3][]const u8, .{
3795 try std.testing.expectError(error.ParseZon, fromSlice([3][]const u8, .{
36793796 .gpa = gpa,
36803797 .arena = arena,
36813798 .source =
......@@ -3685,11 +3802,11 @@ test "std.zon free on error" {
36853802 \\ false,
36863803 \\}
36873804 ,
3688 .errors = null,
3805 .errors = &errors,
36893806 }));
36903807
36913808 // Test freeing partially allocated slices
3692 try std.testing.expectError(error.ParseZon, fromSliceAlloc([][]const u8, .{
3809 try std.testing.expectError(error.ParseZon, fromSlice([][]const u8, .{
36933810 .gpa = gpa,
36943811 .arena = arena,
36953812 .source =
......@@ -3699,28 +3816,29 @@ test "std.zon free on error" {
36993816 \\ false,
37003817 \\}
37013818 ,
3702 .errors = null,
3819 .errors = &errors,
37033820 }));
37043821
37053822 // We can parse types that can't be freed, as long as they contain no allocations, e.g. untagged
37063823 // unions.
37073824 try std.testing.expectEqual(
37083825 @as(f32, 1.5),
3709 (try fromSlice(union { x: f32 }, .{
3826 (try fromSliceNoAlloc(union { x: f32 }, .{
37103827 .gpa = gpa,
3828 .arena = arena,
37113829 .source = ".{ .x = 1.5 }",
3712 .errors = null,
3830 .errors = &errors,
37133831 })).x,
37143832 );
37153833
37163834 // We can also parse types that can't be freed if it's impossible for an error to occur after
37173835 // the allocation, as is the case here.
37183836 {
3719 const result = try fromSliceAlloc(union { x: []const u8 }, .{
3837 const result = try fromSlice(union { x: []const u8 }, .{
37203838 .gpa = gpa,
37213839 .arena = arena,
37223840 .source = ".{ .x = \"foo\" }",
3723 .errors = null,
3841 .errors = &errors,
37243842 });
37253843 try std.testing.expectEqualStrings("foo", result.x);
37263844 }
......@@ -3734,74 +3852,81 @@ test "std.zon vector" {
37343852 var arena_allocator: ArenaAllocator = .init(gpa);
37353853 defer arena_allocator.deinit();
37363854 const arena = arena_allocator.allocator();
3855 var errors: Errors = .empty;
37373856
37383857 // Passing cases
37393858 try std.testing.expectEqual(
37403859 @Vector(0, bool){},
3741 try fromSlice(@Vector(0, bool), .{
3860 try fromSliceNoAlloc(@Vector(0, bool), .{
37423861 .gpa = gpa,
3862 .arena = arena,
37433863 .source = ".{}",
3744 .errors = null,
3864 .errors = &errors,
37453865 }),
37463866 );
37473867 try std.testing.expectEqual(
37483868 @Vector(3, bool){ true, false, true },
3749 try fromSlice(@Vector(3, bool), .{
3869 try fromSliceNoAlloc(@Vector(3, bool), .{
37503870 .gpa = gpa,
3871 .arena = arena,
37513872 .source = ".{true, false, true}",
3752 .errors = null,
3873 .errors = &errors,
37533874 }),
37543875 );
37553876
37563877 try std.testing.expectEqual(
37573878 @Vector(0, f32){},
3758 try fromSlice(@Vector(0, f32), .{
3879 try fromSliceNoAlloc(@Vector(0, f32), .{
37593880 .gpa = gpa,
3881 .arena = arena,
37603882 .source = ".{}",
3761 .errors = null,
3883 .errors = &errors,
37623884 }),
37633885 );
37643886 try std.testing.expectEqual(
37653887 @Vector(3, f32){ 1.5, 2.5, 3.5 },
3766 try fromSlice(@Vector(3, f32), .{
3888 try fromSliceNoAlloc(@Vector(3, f32), .{
37673889 .gpa = gpa,
3890 .arena = arena,
37683891 .source = ".{1.5, 2.5, 3.5}",
3769 .errors = null,
3892 .errors = &errors,
37703893 }),
37713894 );
37723895
37733896 try std.testing.expectEqual(
37743897 @Vector(0, u8){},
3775 try fromSlice(@Vector(0, u8), .{
3898 try fromSliceNoAlloc(@Vector(0, u8), .{
37763899 .gpa = gpa,
3900 .arena = arena,
37773901 .source = ".{}",
3778 .errors = null,
3902 .errors = &errors,
37793903 }),
37803904 );
37813905 try std.testing.expectEqual(
37823906 @Vector(3, u8){ 2, 4, 6 },
3783 try fromSlice(@Vector(3, u8), .{
3907 try fromSliceNoAlloc(@Vector(3, u8), .{
37843908 .gpa = gpa,
3909 .arena = arena,
37853910 .source = ".{2, 4, 6}",
3786 .errors = null,
3911 .errors = &errors,
37873912 }),
37883913 );
37893914
37903915 {
37913916 try std.testing.expectEqual(
37923917 @Vector(0, *const u8){},
3793 try fromSliceAlloc(@Vector(0, *const u8), .{
3918 try fromSlice(@Vector(0, *const u8), .{
37943919 .gpa = gpa,
37953920 .arena = arena,
37963921 .source = ".{}",
3797 .errors = null,
3922 .errors = &errors,
37983923 }),
37993924 );
3800 const pointers = try fromSliceAlloc(@Vector(3, *const u8), .{
3925 const pointers = try fromSlice(@Vector(3, *const u8), .{
38013926 .gpa = gpa,
38023927 .arena = arena,
38033928 .source = ".{2, 4, 6}",
3804 .errors = null,
3929 .errors = &errors,
38053930 });
38063931 try std.testing.expectEqualDeep(@Vector(3, *const u8){ &2, &4, &6 }, pointers);
38073932 }
......@@ -3809,96 +3934,99 @@ test "std.zon vector" {
38093934 {
38103935 try std.testing.expectEqual(
38113936 @Vector(0, ?*const u8){},
3812 try fromSliceAlloc(@Vector(0, ?*const u8), .{
3937 try fromSlice(@Vector(0, ?*const u8), .{
38133938 .gpa = gpa,
38143939 .arena = arena,
38153940 .source = ".{}",
3816 .errors = null,
3941 .errors = &errors,
38173942 }),
38183943 );
3819 const pointers = try fromSliceAlloc(@Vector(3, ?*const u8), .{
3944 const pointers = try fromSlice(@Vector(3, ?*const u8), .{
38203945 .gpa = gpa,
38213946 .arena = arena,
38223947 .source = ".{2, null, 6}",
3823 .errors = null,
3948 .errors = &errors,
38243949 });
38253950 try std.testing.expectEqualDeep(@Vector(3, ?*const u8){ &2, null, &6 }, pointers);
38263951 }
38273952
38283953 // Too few fields
38293954 {
3830 var errors: Errors = .init(arena);
38313955 try std.testing.expectError(
38323956 error.ParseZon,
3833 fromSlice(@Vector(2, f32), .{
3957 fromSliceNoAlloc(@Vector(2, f32), .{
38343958 .gpa = gpa,
3959 .arena = arena,
38353960 .source = ".{0.5}",
38363961 .errors = &errors,
38373962 }),
38383963 );
38393964 try std.testing.expectFmt(
3965 \\input.zon: error.ParseZon
38403966 \\input.zon:1:2: error: expected 2 array elements; found 1
38413967 \\
3842 , "{f}", .{errors.fmt("input.zon")});
3968 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
38433969 }
38443970
38453971 // Too many fields
38463972 {
3847 var errors: Errors = .init(arena);
38483973 try std.testing.expectError(
38493974 error.ParseZon,
3850 fromSlice(@Vector(2, f32), .{
3975 fromSliceNoAlloc(@Vector(2, f32), .{
38513976 .gpa = gpa,
3977 .arena = arena,
38523978 .source = ".{0.5, 1.5, 2.5}",
38533979 .errors = &errors,
38543980 }),
38553981 );
38563982 try std.testing.expectFmt(
3983 \\input.zon: error.ParseZon
38573984 \\input.zon:1:13: error: index 2 outside of array of length 2
38583985 \\
3859 , "{f}", .{errors.fmt("input.zon")});
3986 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
38603987 }
38613988
38623989 // Wrong type fields
38633990 {
3864 var errors: Errors = .init(arena);
38653991 try std.testing.expectError(
38663992 error.ParseZon,
3867 fromSlice(@Vector(3, f32), .{
3993 fromSliceNoAlloc(@Vector(3, f32), .{
38683994 .gpa = gpa,
3995 .arena = arena,
38693996 .source = ".{0.5, true, 2.5}",
38703997 .errors = &errors,
38713998 }),
38723999 );
38734000 try std.testing.expectFmt(
4001 \\input.zon: error.ParseZon
38744002 \\input.zon:1:8: error: expected type 'f32'
38754003 \\
3876 , "{f}", .{errors.fmt("input.zon")});
4004 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
38774005 }
38784006
38794007 // Wrong type
38804008 {
3881 var errors: Errors = .init(arena);
38824009 try std.testing.expectError(
38834010 error.ParseZon,
3884 fromSlice(@Vector(3, u8), .{
4011 fromSliceNoAlloc(@Vector(3, u8), .{
38854012 .gpa = gpa,
4013 .arena = arena,
38864014 .source = "true",
38874015 .errors = &errors,
38884016 }),
38894017 );
38904018 try std.testing.expectFmt(
4019 \\input.zon: error.ParseZon
38914020 \\input.zon:1:1: error: expected type '@Vector(3, u8)'
38924021 \\
3893 , "{f}", .{errors.fmt("input.zon")});
4022 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
38944023 }
38954024
38964025 // Elements should get freed on error
38974026 {
3898 var errors: Errors = .init(arena);
38994027 try std.testing.expectError(
39004028 error.ParseZon,
3901 fromSliceAlloc(@Vector(3, *u8), .{
4029 fromSlice(@Vector(3, *u8), .{
39024030 .gpa = gpa,
39034031 .arena = arena,
39044032 .source = ".{1, true, 3}",
......@@ -3906,9 +4034,10 @@ test "std.zon vector" {
39064034 }),
39074035 );
39084036 try std.testing.expectFmt(
4037 \\input.zon: error.ParseZon
39094038 \\input.zon:1:6: error: expected type 'u8'
39104039 \\
3911 , "{f}", .{errors.fmt("input.zon")});
4040 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
39124041 }
39134042}
39144043
......@@ -3917,136 +4046,137 @@ test "std.zon add pointers" {
39174046 var arena_allocator: ArenaAllocator = .init(gpa);
39184047 defer arena_allocator.deinit();
39194048 const arena = arena_allocator.allocator();
4049 var errors: Errors = .empty;
39204050
39214051 // Primitive with varying levels of pointers
39224052 {
3923 const result = try fromSliceAlloc(*u32, .{
4053 const result = try fromSlice(*u32, .{
39244054 .gpa = gpa,
39254055 .arena = arena,
39264056 .source = "10",
3927 .errors = null,
4057 .errors = &errors,
39284058 });
39294059 try std.testing.expectEqual(@as(u32, 10), result.*);
39304060 }
39314061
39324062 {
3933 const result = try fromSliceAlloc(**u32, .{
4063 const result = try fromSlice(**u32, .{
39344064 .gpa = gpa,
39354065 .arena = arena,
39364066 .source = "10",
3937 .errors = null,
4067 .errors = &errors,
39384068 });
39394069 try std.testing.expectEqual(@as(u32, 10), result.*.*);
39404070 }
39414071
39424072 {
3943 const result = try fromSliceAlloc(***u32, .{
4073 const result = try fromSlice(***u32, .{
39444074 .gpa = gpa,
39454075 .arena = arena,
39464076 .source = "10",
3947 .errors = null,
4077 .errors = &errors,
39484078 });
39494079 try std.testing.expectEqual(@as(u32, 10), result.*.*.*);
39504080 }
39514081
39524082 // Primitive optional with varying levels of pointers
39534083 {
3954 const some = try fromSliceAlloc(?*u32, .{
4084 const some = try fromSlice(?*u32, .{
39554085 .gpa = gpa,
39564086 .arena = arena,
39574087 .source = "10",
3958 .errors = null,
4088 .errors = &errors,
39594089 });
39604090 try std.testing.expectEqual(@as(u32, 10), some.?.*);
39614091
3962 const none = try fromSliceAlloc(?*u32, .{
4092 const none = try fromSlice(?*u32, .{
39634093 .gpa = gpa,
39644094 .arena = arena,
39654095 .source = "null",
3966 .errors = null,
4096 .errors = &errors,
39674097 });
39684098 try std.testing.expectEqual(null, none);
39694099 }
39704100
39714101 {
3972 const some = try fromSliceAlloc(*?u32, .{
4102 const some = try fromSlice(*?u32, .{
39734103 .gpa = gpa,
39744104 .arena = arena,
39754105 .source = "10",
3976 .errors = null,
4106 .errors = &errors,
39774107 });
39784108 try std.testing.expectEqual(@as(u32, 10), some.*.?);
39794109
3980 const none = try fromSliceAlloc(*?u32, .{
4110 const none = try fromSlice(*?u32, .{
39814111 .gpa = gpa,
39824112 .arena = arena,
39834113 .source = "null",
3984 .errors = null,
4114 .errors = &errors,
39854115 });
39864116 try std.testing.expectEqual(null, none.*);
39874117 }
39884118
39894119 {
3990 const some = try fromSliceAlloc(?**u32, .{
4120 const some = try fromSlice(?**u32, .{
39914121 .gpa = gpa,
39924122 .arena = arena,
39934123 .source = "10",
3994 .errors = null,
4124 .errors = &errors,
39954125 });
39964126 try std.testing.expectEqual(@as(u32, 10), some.?.*.*);
39974127
3998 const none = try fromSliceAlloc(?**u32, .{
4128 const none = try fromSlice(?**u32, .{
39994129 .gpa = gpa,
40004130 .arena = arena,
40014131 .source = "null",
4002 .errors = null,
4132 .errors = &errors,
40034133 });
40044134 try std.testing.expectEqual(null, none);
40054135 }
40064136
40074137 {
4008 const some = try fromSliceAlloc(*?*u32, .{
4138 const some = try fromSlice(*?*u32, .{
40094139 .gpa = gpa,
40104140 .arena = arena,
40114141 .source = "10",
4012 .errors = null,
4142 .errors = &errors,
40134143 });
40144144 try std.testing.expectEqual(@as(u32, 10), some.*.?.*);
40154145
4016 const none = try fromSliceAlloc(*?*u32, .{
4146 const none = try fromSlice(*?*u32, .{
40174147 .gpa = gpa,
40184148 .arena = arena,
40194149 .source = "null",
4020 .errors = null,
4150 .errors = &errors,
40214151 });
40224152 try std.testing.expectEqual(null, none.*);
40234153 }
40244154
40254155 {
4026 const some = try fromSliceAlloc(**?u32, .{
4156 const some = try fromSlice(**?u32, .{
40274157 .gpa = gpa,
40284158 .arena = arena,
40294159 .source = "10",
4030 .errors = null,
4160 .errors = &errors,
40314161 });
40324162 try std.testing.expectEqual(@as(u32, 10), some.*.*.?);
40334163
4034 const none = try fromSliceAlloc(**?u32, .{
4164 const none = try fromSlice(**?u32, .{
40354165 .gpa = gpa,
40364166 .arena = arena,
40374167 .source = "null",
4038 .errors = null,
4168 .errors = &errors,
40394169 });
40404170 try std.testing.expectEqual(null, none.*.*);
40414171 }
40424172
40434173 // Pointer to an array
40444174 {
4045 const result = try fromSliceAlloc(*[3]u8, .{
4175 const result = try fromSlice(*[3]u8, .{
40464176 .gpa = gpa,
40474177 .arena = arena,
40484178 .source = ".{ 1, 2, 3 }",
4049 .errors = null,
4179 .errors = &errors,
40504180 });
40514181 try std.testing.expectEqual([3]u8{ 1, 2, 3 }, result.*);
40524182 }
......@@ -4069,7 +4199,7 @@ test "std.zon add pointers" {
40694199 .f2 = &null,
40704200 };
40714201
4072 const found = try fromSliceAlloc(?*Outer, .{
4202 const found = try fromSlice(?*Outer, .{
40734203 .gpa = gpa,
40744204 .arena = arena,
40754205 .source =
......@@ -4081,7 +4211,7 @@ test "std.zon add pointers" {
40814211 \\ .f2 = null,
40824212 \\}
40834213 ,
4084 .errors = null,
4214 .errors = &errors,
40854215 });
40864216
40874217 try std.testing.expectEqualDeep(expected, found.?.*);
......@@ -4089,10 +4219,9 @@ test "std.zon add pointers" {
40894219
40904220 // Test that optional types are flattened correctly in errors
40914221 {
4092 var errors: Errors = .init(arena);
40934222 try std.testing.expectError(
40944223 error.ParseZon,
4095 fromSliceAlloc(*const ?*const u8, .{
4224 fromSlice(*const ?*const u8, .{
40964225 .gpa = gpa,
40974226 .arena = arena,
40984227 .source = "true",
......@@ -4100,16 +4229,16 @@ test "std.zon add pointers" {
41004229 }),
41014230 );
41024231 try std.testing.expectFmt(
4232 \\input.zon: error.ParseZon
41034233 \\input.zon:1:1: error: expected type '?u8'
41044234 \\
4105 , "{f}", .{errors.fmt("input.zon")});
4235 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41064236 }
41074237
41084238 {
4109 var errors: Errors = .init(arena);
41104239 try std.testing.expectError(
41114240 error.ParseZon,
4112 fromSliceAlloc(*const ?*const f32, .{
4241 fromSlice(*const ?*const f32, .{
41134242 .gpa = gpa,
41144243 .arena = arena,
41154244 .source = "true",
......@@ -4117,16 +4246,16 @@ test "std.zon add pointers" {
41174246 }),
41184247 );
41194248 try std.testing.expectFmt(
4249 \\input.zon: error.ParseZon
41204250 \\input.zon:1:1: error: expected type '?f32'
41214251 \\
4122 , "{f}", .{errors.fmt("input.zon")});
4252 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41234253 }
41244254
41254255 {
4126 var errors: Errors = .init(arena);
41274256 try std.testing.expectError(
41284257 error.ParseZon,
4129 fromSliceAlloc(*const ?*const @Vector(3, u8), .{
4258 fromSlice(*const ?*const @Vector(3, u8), .{
41304259 .gpa = gpa,
41314260 .arena = arena,
41324261 .source = "true",
......@@ -4134,16 +4263,16 @@ test "std.zon add pointers" {
41344263 }),
41354264 );
41364265 try std.testing.expectFmt(
4266 \\input.zon: error.ParseZon
41374267 \\input.zon:1:1: error: expected type '?@Vector(3, u8)'
41384268 \\
4139 , "{f}", .{errors.fmt("input.zon")});
4269 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41404270 }
41414271
41424272 {
4143 var errors: Errors = .init(arena);
41444273 try std.testing.expectError(
41454274 error.ParseZon,
4146 fromSliceAlloc(*const ?*const bool, .{
4275 fromSlice(*const ?*const bool, .{
41474276 .gpa = gpa,
41484277 .arena = arena,
41494278 .source = "10",
......@@ -4151,16 +4280,16 @@ test "std.zon add pointers" {
41514280 }),
41524281 );
41534282 try std.testing.expectFmt(
4283 \\input.zon: error.ParseZon
41544284 \\input.zon:1:1: error: expected type '?bool'
41554285 \\
4156 , "{f}", .{errors.fmt("input.zon")});
4286 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41574287 }
41584288
41594289 {
4160 var errors: Errors = .init(arena);
41614290 try std.testing.expectError(
41624291 error.ParseZon,
4163 fromSliceAlloc(*const ?*const struct { a: i32 }, .{
4292 fromSlice(*const ?*const struct { a: i32 }, .{
41644293 .gpa = gpa,
41654294 .arena = arena,
41664295 .source = "true",
......@@ -4168,16 +4297,16 @@ test "std.zon add pointers" {
41684297 }),
41694298 );
41704299 try std.testing.expectFmt(
4300 \\input.zon: error.ParseZon
41714301 \\input.zon:1:1: error: expected optional struct
41724302 \\
4173 , "{f}", .{errors.fmt("input.zon")});
4303 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41744304 }
41754305
41764306 {
4177 var errors: Errors = .init(arena);
41784307 try std.testing.expectError(
41794308 error.ParseZon,
4180 fromSliceAlloc(*const ?*const struct { i32 }, .{
4309 fromSlice(*const ?*const struct { i32 }, .{
41814310 .gpa = gpa,
41824311 .arena = arena,
41834312 .source = "true",
......@@ -4185,16 +4314,16 @@ test "std.zon add pointers" {
41854314 }),
41864315 );
41874316 try std.testing.expectFmt(
4317 \\input.zon: error.ParseZon
41884318 \\input.zon:1:1: error: expected optional tuple
41894319 \\
4190 , "{f}", .{errors.fmt("input.zon")});
4320 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
41914321 }
41924322
41934323 {
4194 var errors: Errors = .init(arena);
41954324 try std.testing.expectError(
41964325 error.ParseZon,
4197 fromSliceAlloc(*const ?*const union { x: void }, .{
4326 fromSlice(*const ?*const union { x: void }, .{
41984327 .gpa = gpa,
41994328 .arena = arena,
42004329 .source = "true",
......@@ -4202,16 +4331,16 @@ test "std.zon add pointers" {
42024331 }),
42034332 );
42044333 try std.testing.expectFmt(
4334 \\input.zon: error.ParseZon
42054335 \\input.zon:1:1: error: expected optional union
42064336 \\
4207 , "{f}", .{errors.fmt("input.zon")});
4337 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42084338 }
42094339
42104340 {
4211 var errors: Errors = .init(arena);
42124341 try std.testing.expectError(
42134342 error.ParseZon,
4214 fromSliceAlloc(*const ?*const [3]u8, .{
4343 fromSlice(*const ?*const [3]u8, .{
42154344 .gpa = gpa,
42164345 .arena = arena,
42174346 .source = "true",
......@@ -4219,16 +4348,16 @@ test "std.zon add pointers" {
42194348 }),
42204349 );
42214350 try std.testing.expectFmt(
4351 \\input.zon: error.ParseZon
42224352 \\input.zon:1:1: error: expected optional array
42234353 \\
4224 , "{f}", .{errors.fmt("input.zon")});
4354 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42254355 }
42264356
42274357 {
4228 var errors: Errors = .init(arena);
42294358 try std.testing.expectError(
42304359 error.ParseZon,
4231 fromSliceAlloc(?[3]u8, .{
4360 fromSlice(?[3]u8, .{
42324361 .gpa = gpa,
42334362 .arena = arena,
42344363 .source = "true",
......@@ -4236,16 +4365,16 @@ test "std.zon add pointers" {
42364365 }),
42374366 );
42384367 try std.testing.expectFmt(
4368 \\input.zon: error.ParseZon
42394369 \\input.zon:1:1: error: expected optional array
42404370 \\
4241 , "{f}", .{errors.fmt("input.zon")});
4371 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42424372 }
42434373
42444374 {
4245 var errors: Errors = .init(arena);
42464375 try std.testing.expectError(
42474376 error.ParseZon,
4248 fromSliceAlloc(*const ?*const []u8, .{
4377 fromSlice(*const ?*const []u8, .{
42494378 .gpa = gpa,
42504379 .arena = arena,
42514380 .source = "true",
......@@ -4253,16 +4382,16 @@ test "std.zon add pointers" {
42534382 }),
42544383 );
42554384 try std.testing.expectFmt(
4385 \\input.zon: error.ParseZon
42564386 \\input.zon:1:1: error: expected optional array
42574387 \\
4258 , "{f}", .{errors.fmt("input.zon")});
4388 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42594389 }
42604390
42614391 {
4262 var errors: Errors = .init(arena);
42634392 try std.testing.expectError(
42644393 error.ParseZon,
4265 fromSliceAlloc(?[]u8, .{
4394 fromSlice(?[]u8, .{
42664395 .gpa = gpa,
42674396 .arena = arena,
42684397 .source = "true",
......@@ -4270,16 +4399,16 @@ test "std.zon add pointers" {
42704399 }),
42714400 );
42724401 try std.testing.expectFmt(
4402 \\input.zon: error.ParseZon
42734403 \\input.zon:1:1: error: expected optional array
42744404 \\
4275 , "{f}", .{errors.fmt("input.zon")});
4405 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42764406 }
42774407
42784408 {
4279 var errors: Errors = .init(arena);
42804409 try std.testing.expectError(
42814410 error.ParseZon,
4282 fromSliceAlloc(*const ?*const []const u8, .{
4411 fromSlice(*const ?*const []const u8, .{
42834412 .gpa = gpa,
42844413 .arena = arena,
42854414 .source = "true",
......@@ -4287,16 +4416,16 @@ test "std.zon add pointers" {
42874416 }),
42884417 );
42894418 try std.testing.expectFmt(
4419 \\input.zon: error.ParseZon
42904420 \\input.zon:1:1: error: expected optional string
42914421 \\
4292 , "{f}", .{errors.fmt("input.zon")});
4422 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
42934423 }
42944424
42954425 {
4296 var errors: Errors = .init(arena);
42974426 try std.testing.expectError(
42984427 error.ParseZon,
4299 fromSliceAlloc(*const ?*const enum { foo }, .{
4428 fromSlice(*const ?*const enum { foo }, .{
43004429 .gpa = gpa,
43014430 .arena = arena,
43024431 .source = "true",
......@@ -4304,14 +4433,19 @@ test "std.zon add pointers" {
43044433 }),
43054434 );
43064435 try std.testing.expectFmt(
4436 \\input.zon: error.ParseZon
43074437 \\input.zon:1:1: error: expected optional enum literal
43084438 \\
4309 , "{f}", .{errors.fmt("input.zon")});
4439 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
43104440 }
43114441}
43124442
43134443test "std.zon stop on node" {
43144444 const gpa = std.testing.allocator;
4445 var arena_allocator: ArenaAllocator = .init(gpa);
4446 defer arena_allocator.deinit();
4447 const arena = arena_allocator.allocator();
4448 var errors: Errors = .empty;
43154449
43164450 {
43174451 const Vec2 = struct {
......@@ -4325,10 +4459,11 @@ test "std.zon stop on node" {
43254459 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
43264460 defer zoir.deinit(gpa);
43274461
4328 const result = try fromZoir(Vec2, .{
4462 const result = try fromZoirNoAlloc(Vec2, .{
4463 .arena = arena,
43294464 .ast = &ast,
43304465 .zoir = &zoir,
4331 .errors = null,
4466 .errors = &errors,
43324467 });
43334468
43344469 try std.testing.expectEqual(result.y, 2.5);
......@@ -4342,10 +4477,11 @@ test "std.zon stop on node" {
43424477 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
43434478 defer zoir.deinit(gpa);
43444479
4345 const result = try fromZoir(Zoir.Node.Index, .{
4480 const result = try fromZoirNoAlloc(Zoir.Node.Index, .{
4481 .arena = arena,
43464482 .ast = &ast,
43474483 .zoir = &zoir,
4348 .errors = null,
4484 .errors = &errors,
43494485 });
43504486 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.23 }, result.get(&zoir));
43514487 }
......@@ -4353,13 +4489,18 @@ test "std.zon stop on node" {
43534489
43544490test "std.zon no alloc" {
43554491 const gpa = std.testing.allocator;
4492 var arena_allocator: ArenaAllocator = .init(gpa);
4493 defer arena_allocator.deinit();
4494 const arena = arena_allocator.allocator();
4495 var errors: Errors = .empty;
43564496
43574497 try std.testing.expectEqual(
43584498 [3]u8{ 1, 2, 3 },
4359 try fromSlice([3]u8, .{
4499 try fromSliceNoAlloc([3]u8, .{
43604500 .gpa = gpa,
4501 .arena = arena,
43614502 .source = ".{ 1, 2, 3 }",
4362 .errors = null,
4503 .errors = &errors,
43634504 }),
43644505 );
43654506
......@@ -4373,10 +4514,11 @@ test "std.zon no alloc" {
43734514
43744515 try std.testing.expectEqual(
43754516 Nested{ 1, 2, .{ 3, 4 } },
4376 try fromZoir(Nested, .{
4517 try fromZoirNoAlloc(Nested, .{
4518 .arena = arena,
43774519 .ast = &ast,
43784520 .zoir = &zoir,
4379 .errors = null,
4521 .errors = &errors,
43804522 }),
43814523 );
43824524}
......@@ -4386,44 +4528,45 @@ test "std.zon errors without errorsnostics" {
43864528 var arena_allocator: ArenaAllocator = .init(gpa);
43874529 defer arena_allocator.deinit();
43884530 const arena = arena_allocator.allocator();
4531 var errors: Errors = .empty;
43894532
43904533 const Enum = enum {
43914534 foo,
43924535 bar,
43934536 baz,
43944537 };
4395 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Enum, .{
4538 try std.testing.expectError(error.ParseZon, fromSlice(Enum, .{
43964539 .gpa = gpa,
43974540 .arena = arena,
43984541 .source = ".nothing",
4399 .errors = null,
4542 .errors = &errors,
44004543 }));
44014544
44024545 const Struct = struct {
44034546 name: []const u8,
44044547 };
4405 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
4548 try std.testing.expectError(error.ParseZon, fromSlice(Struct, .{
44064549 .gpa = gpa,
44074550 .arena = arena,
44084551 .source = ".{ .name = \"Alice\", .age = 25 }",
4409 .errors = null,
4552 .errors = &errors,
44104553 }));
44114554
44124555 const Union = union(enum) {
44134556 x,
44144557 y: u32,
44154558 };
4416 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
4559 try std.testing.expectError(error.ParseZon, fromSlice(Union, .{
44174560 .gpa = gpa,
44184561 .arena = arena,
44194562 .source = ".a",
4420 .errors = null,
4563 .errors = &errors,
44214564 }));
4422 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
4565 try std.testing.expectError(error.ParseZon, fromSlice(Union, .{
44234566 .gpa = gpa,
44244567 .arena = arena,
44254568 .source = ".{ .b = 8 }",
4426 .errors = null,
4569 .errors = &errors,
44274570 }));
44284571}
44294572
......@@ -4432,6 +4575,7 @@ test "std.zon aligned pointers" {
44324575 var arena_allocator: ArenaAllocator = .init(gpa);
44334576 defer arena_allocator.deinit();
44344577 const arena = arena_allocator.allocator();
4578 var errors: Errors = .empty;
44354579
44364580 const n: u8 align(8) = 10;
44374581 const Foo = struct {
......@@ -4441,11 +4585,11 @@ test "std.zon aligned pointers" {
44414585 const expected: Foo = .{
44424586 .inner = &n,
44434587 };
4444 const found = try fromSliceAlloc(Foo, .{
4588 const found = try fromSlice(Foo, .{
44454589 .gpa = gpa,
44464590 .arena = arena,
44474591 .source = ".{ .inner = 10 }",
4448 .errors = null,
4592 .errors = &errors,
44494593 });
44504594 try std.testing.expectEqualDeep(expected.inner, found.inner);
44514595}
......@@ -4455,6 +4599,7 @@ test "std.zon update basic" {
44554599 var arena_allocator: ArenaAllocator = .init(gpa);
44564600 defer arena_allocator.deinit();
44574601 const arena = arena_allocator.allocator();
4602 var errors: Errors = .empty;
44584603
44594604 const Vector = struct { x: f32, y: f32, z: f32 };
44604605 const MyStruct = struct {
......@@ -4486,77 +4631,77 @@ test "std.zon update basic" {
44864631 .str = "hello, world",
44874632 };
44884633
4489 try updateFromSliceAlloc(MyStruct, &found, .{
4634 try updateFromSlice(MyStruct, &found, .{
44904635 .gpa = gpa,
44914636 .arena = arena,
44924637 .source = ".{}",
4493 .errors = null,
4638 .errors = &errors,
44944639 });
44954640 try std.testing.expectEqualDeep(expected, found);
44964641
4497 try updateFromSliceAlloc(MyStruct, &found, .{
4642 try updateFromSlice(MyStruct, &found, .{
44984643 .gpa = gpa,
44994644 .arena = arena,
45004645 .source = ".{ .bar = false }",
4501 .errors = null,
4646 .errors = &errors,
45024647 });
45034648 expected.bar = false;
45044649 try std.testing.expectEqualDeep(expected, found);
45054650
4506 try updateFromSliceAlloc(MyStruct, &found, .{
4651 try updateFromSlice(MyStruct, &found, .{
45074652 .gpa = gpa,
45084653 .arena = arena,
45094654 .source = ".{ .baz = .{ .a = .{ 2, 4 } } }",
4510 .errors = null,
4655 .errors = &errors,
45114656 });
45124657 expected.baz.a[0] = 2;
45134658 expected.baz.a[1] = 4;
45144659 try std.testing.expectEqualDeep(expected, found);
45154660
4516 try updateFromSliceAlloc(MyStruct, &found, .{
4661 try updateFromSlice(MyStruct, &found, .{
45174662 .gpa = gpa,
45184663 .arena = arena,
45194664 .source = ".{ .foo = 11, .baz = .{ .b = .d } }",
4520 .errors = null,
4665 .errors = &errors,
45214666 });
45224667 expected.foo = 11;
45234668 expected.baz.b = .d;
45244669 try std.testing.expectEqualDeep(expected, found);
45254670
4526 try updateFromSliceAlloc(MyStruct, &found, .{
4671 try updateFromSlice(MyStruct, &found, .{
45274672 .gpa = gpa,
45284673 .arena = arena,
45294674 .source = ".{ .optional = 10 }",
4530 .errors = null,
4675 .errors = &errors,
45314676 });
45324677 expected.optional = 10;
45334678 try std.testing.expectEqualDeep(expected, found);
45344679
4535 try updateFromSliceAlloc(MyStruct, &found, .{
4680 try updateFromSlice(MyStruct, &found, .{
45364681 .gpa = gpa,
45374682 .arena = arena,
45384683 .source = ".{ .optional = null }",
4539 .errors = null,
4684 .errors = &errors,
45404685 });
45414686 expected.optional = null;
45424687 try std.testing.expectEqualDeep(expected, found);
45434688
4544 try updateFromSliceAlloc(MyStruct, &found, .{
4689 try updateFromSlice(MyStruct, &found, .{
45454690 .gpa = gpa,
45464691 .arena = arena,
45474692 .source = ".{ .ptr = .{ .x = 10, .y = 20, .z = 30 } }",
4548 .errors = null,
4693 .errors = &errors,
45494694 });
45504695 expected.ptr.x = 10;
45514696 expected.ptr.y = 20;
45524697 expected.ptr.z = 30;
45534698 try std.testing.expectEqualDeep(expected, found);
45544699
4555 try updateFromSliceAlloc(MyStruct, &found, .{
4700 try updateFromSlice(MyStruct, &found, .{
45564701 .gpa = gpa,
45574702 .arena = arena,
45584703 .source = ".{ .str = \"foo\" }",
4559 .errors = null,
4704 .errors = &errors,
45604705 });
45614706 expected.str = "foo";
45624707 try std.testing.expectEqualDeep(expected, found);
......@@ -4567,6 +4712,7 @@ test "std.zon update optionals" {
45674712 var arena_allocator: ArenaAllocator = .init(gpa);
45684713 defer arena_allocator.deinit();
45694714 const arena = arena_allocator.allocator();
4715 var errors: Errors = .empty;
45704716
45714717 const MyStruct = struct {
45724718 foo: ?struct { bar: u32 = 1, baz: u32 = 2, qux: u32 },
......@@ -4576,10 +4722,11 @@ test "std.zon update optionals" {
45764722 {
45774723 var expected: MyStruct = .{ .foo = null };
45784724 var found = expected;
4579 try updateFromSlice(MyStruct, &found, .{
4725 try updateFromSliceNoAlloc(MyStruct, &found, .{
45804726 .gpa = gpa,
4727 .arena = arena,
45814728 .source = ".{ .foo = .{ .qux = 3 } }",
4582 .errors = null,
4729 .errors = &errors,
45834730 });
45844731 expected.foo = .{ .qux = 3 };
45854732 try std.testing.expectEqual(expected, found);
......@@ -4588,16 +4735,17 @@ test "std.zon update optionals" {
45884735 // Updating an optional that starts out null should error if we leave off required fields.
45894736 {
45904737 var found: MyStruct = .{ .foo = null };
4591 var errors: Errors = .init(arena);
4592 try std.testing.expectError(error.ParseZon, updateFromSlice(MyStruct, &found, .{
4738 try std.testing.expectError(error.ParseZon, updateFromSliceNoAlloc(MyStruct, &found, .{
45934739 .gpa = gpa,
4740 .arena = arena,
45944741 .source = ".{ .foo = .{} }",
45954742 .errors = &errors,
45964743 }));
45974744 try std.testing.expectFmt(
4745 \\input.zon: error.ParseZon
45984746 \\input.zon:1:12: error: missing required field qux
45994747 \\
4600 , "{f}", .{errors.fmt("input.zon")});
4748 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
46014749 }
46024750
46034751 // Updating an optional that starts out non-null should preserve any values we leave off. It's
......@@ -4607,10 +4755,11 @@ test "std.zon update optionals" {
46074755 .foo = .{ .bar = 10, .baz = 20, .qux = 30 },
46084756 };
46094757 var found = expected;
4610 try updateFromSlice(MyStruct, &found, .{
4758 try updateFromSliceNoAlloc(MyStruct, &found, .{
46114759 .gpa = gpa,
4760 .arena = arena,
46124761 .source = ".{ .foo = .{ .baz = 200 } }",
4613 .errors = null,
4762 .errors = &errors,
46144763 });
46154764 expected.foo.?.baz = 200;
46164765 try std.testing.expectEqual(expected, found);
......@@ -4622,6 +4771,7 @@ test "std.zon update optional pointers" {
46224771 var arena_allocator: ArenaAllocator = .init(gpa);
46234772 defer arena_allocator.deinit();
46244773 const arena = arena_allocator.allocator();
4774 var errors: Errors = .empty;
46254775
46264776 const MyStruct = struct {
46274777 foo: ?*const struct { bar: u32 = 1, baz: u32 = 2, qux: u32 },
......@@ -4631,11 +4781,11 @@ test "std.zon update optional pointers" {
46314781 {
46324782 var expected: MyStruct = .{ .foo = null };
46334783 var found = expected;
4634 try updateFromSliceAlloc(MyStruct, &found, .{
4784 try updateFromSlice(MyStruct, &found, .{
46354785 .gpa = gpa,
46364786 .arena = arena,
46374787 .source = ".{ .foo = .{ .qux = 3 } }",
4638 .errors = null,
4788 .errors = &errors,
46394789 });
46404790 expected.foo = &.{ .qux = 3 };
46414791 try std.testing.expectEqualDeep(expected, found);
......@@ -4647,6 +4797,7 @@ test "std.zon update pointers" {
46474797 var arena_allocator: ArenaAllocator = .init(gpa);
46484798 defer arena_allocator.deinit();
46494799 const arena = arena_allocator.allocator();
4800 var errors: Errors = .empty;
46504801
46514802 // Updating a pointer should leave fields we don't specify unchanged
46524803 {
......@@ -4656,11 +4807,11 @@ test "std.zon update pointers" {
46564807 var ptr: @typeInfo(@FieldType(MyStruct, "foo")).pointer.child = .{ .qux = 3 };
46574808 var expected: MyStruct = .{ .foo = &ptr };
46584809 var found = expected;
4659 try updateFromSliceAlloc(MyStruct, &found, .{
4810 try updateFromSlice(MyStruct, &found, .{
46604811 .gpa = gpa,
46614812 .arena = arena,
46624813 .source = ".{ .foo = .{ .bar = 100 } }",
4663 .errors = null,
4814 .errors = &errors,
46644815 });
46654816 expected.foo.bar = 100;
46664817 try std.testing.expectEqualDeep(expected, found);
......@@ -4673,11 +4824,11 @@ test "std.zon update pointers" {
46734824 };
46744825 var expected: MyStruct = .{ .foo = &.{ .qux = 3 } };
46754826 var found = expected;
4676 try updateFromSliceAlloc(MyStruct, &found, .{
4827 try updateFromSlice(MyStruct, &found, .{
46774828 .gpa = gpa,
46784829 .arena = arena,
46794830 .source = ".{ .foo = .{ .bar = 100 } }",
4680 .errors = null,
4831 .errors = &errors,
46814832 });
46824833 expected.foo = &.{ .bar = 100, .baz = 20, .qux = 3 };
46834834 try std.testing.expectEqualDeep(expected, found);
......@@ -4689,6 +4840,7 @@ test "std.zon update unions" {
46894840 var arena_allocator: ArenaAllocator = .init(gpa);
46904841 defer arena_allocator.deinit();
46914842 const arena = arena_allocator.allocator();
4843 var errors: Errors = .empty;
46924844
46934845 const MyUnion = union(enum) {
46944846 none: void,
......@@ -4699,10 +4851,11 @@ test "std.zon update unions" {
46994851 {
47004852 var expected: MyUnion = .none;
47014853 var found = expected;
4702 try updateFromSlice(MyUnion, &found, .{
4854 try updateFromSliceNoAlloc(MyUnion, &found, .{
47034855 .gpa = gpa,
4856 .arena = arena,
47044857 .source = ".{ .foo = .{ .qux = 3 } }",
4705 .errors = null,
4858 .errors = &errors,
47064859 });
47074860 expected = .{ .foo = .{ .qux = 3 } };
47084861 try std.testing.expectEqual(expected, found);
......@@ -4711,16 +4864,17 @@ test "std.zon update unions" {
47114864 // Updating a union to a new field should error if we leave off required sub-fields
47124865 {
47134866 var found: MyUnion = .none;
4714 var errors: Errors = .init(arena);
4715 try std.testing.expectError(error.ParseZon, updateFromSlice(MyUnion, &found, .{
4867 try std.testing.expectError(error.ParseZon, updateFromSliceNoAlloc(MyUnion, &found, .{
47164868 .gpa = gpa,
4869 .arena = arena,
47174870 .source = ".{ .foo = .{} }",
47184871 .errors = &errors,
47194872 }));
47204873 try std.testing.expectFmt(
4874 \\input.zon: error.ParseZon
47214875 \\input.zon:1:12: error: missing required field qux
47224876 \\
4723 , "{f}", .{errors.fmt("input.zon")});
4877 , "{f}", .{errors.fmt("input.zon", error.ParseZon)});
47244878 }
47254879
47264880 // Updating a union should preseve any sub-fields that we left off. It's also okay to leave off
......@@ -4730,10 +4884,11 @@ test "std.zon update unions" {
47304884 .foo = .{ .bar = 10, .baz = 20, .qux = 30 },
47314885 };
47324886 var found = expected;
4733 try updateFromSlice(MyUnion, &found, .{
4887 try updateFromSliceNoAlloc(MyUnion, &found, .{
47344888 .gpa = gpa,
4889 .arena = arena,
47354890 .source = ".{ .foo = .{ .baz = 200 } }",
4736 .errors = null,
4891 .errors = &errors,
47374892 });
47384893 expected.foo.baz = 200;
47394894 try std.testing.expectEqual(expected, found);
......@@ -4748,6 +4903,7 @@ test "std.zon variants" {
47484903 var arena_allocator: ArenaAllocator = .init(gpa);
47494904 defer arena_allocator.deinit();
47504905 const arena = arena_allocator.allocator();
4906 var errors: Errors = .empty;
47514907
47524908 const Struct = struct { a: u32, b: u32 };
47534909 const start: Struct = .{ .a = 10, .b = 20 };
......@@ -4761,36 +4917,38 @@ test "std.zon variants" {
47614917 defer zoir.deinit(gpa);
47624918
47634919 var curr = start;
4764 try updateFromSlice(Struct, &curr, .{
4920 try updateFromSliceNoAlloc(Struct, &curr, .{
47654921 .gpa = gpa,
4922 .arena = arena,
47664923 .source = ".{ .a = 100 }",
4767 .errors = null,
4924 .errors = &errors,
47684925 });
47694926 try std.testing.expectEqual(end, curr);
47704927
47714928 curr = start;
4772 try updateFromSliceAlloc(Struct, &curr, .{
4929 try updateFromSlice(Struct, &curr, .{
47734930 .gpa = gpa,
47744931 .arena = arena,
47754932 .source = ".{ .a = 100 }",
4776 .errors = null,
4933 .errors = &errors,
47774934 });
47784935 try std.testing.expectEqual(end, curr);
47794936
47804937 curr = start;
4781 try updateFromZoir(Struct, &curr, .{
4938 try updateFromZoirNoAlloc(Struct, &curr, .{
4939 .arena = arena,
47824940 .ast = &ast,
47834941 .zoir = &zoir,
4784 .errors = null,
4942 .errors = &errors,
47854943 });
47864944 try std.testing.expectEqual(end, curr);
47874945
47884946 curr = start;
4789 try updateFromZoirAlloc(Struct, &curr, .{
4947 try updateFromZoir(Struct, &curr, .{
47904948 .arena = arena,
47914949 .ast = &ast,
47924950 .zoir = &zoir,
4793 .errors = null,
4951 .errors = &errors,
47944952 });
47954953 try std.testing.expectEqual(end, curr);
47964954 }
......@@ -4804,35 +4962,37 @@ test "std.zon variants" {
48044962
48054963 try std.testing.expectEqual(
48064964 end,
4807 try fromSlice(Struct, .{
4965 try fromSliceNoAlloc(Struct, .{
48084966 .gpa = gpa,
4967 .arena = arena,
48094968 .source = ".{ .a = 100, .b = 20 }",
4810 .errors = null,
4969 .errors = &errors,
48114970 }),
48124971 );
48134972 try std.testing.expectEqual(
48144973 end,
4815 try fromSliceAlloc(Struct, .{
4974 try fromSlice(Struct, .{
48164975 .gpa = gpa,
48174976 .arena = arena,
48184977 .source = ".{ .a = 100, .b = 20 }",
4819 .errors = null,
4978 .errors = &errors,
48204979 }),
48214980 );
48224981 try std.testing.expectEqual(
4823 try fromZoir(Struct, .{
4982 try fromZoirNoAlloc(Struct, .{
4983 .arena = arena,
48244984 .ast = &ast,
48254985 .zoir = &zoir,
4826 .errors = null,
4986 .errors = &errors,
48274987 }),
48284988 end,
48294989 );
48304990 try std.testing.expectEqual(
4831 try fromZoirAlloc(Struct, .{
4991 try fromZoir(Struct, .{
48324992 .arena = arena,
48334993 .ast = &ast,
48344994 .zoir = &zoir,
4835 .errors = null,
4995 .errors = &errors,
48364996 }),
48374997 end,
48384998 );