authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-07-17 03:23:14-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
log09e69d88ed0e3b8cf3c65aec4559614a835021a9
tree4d328364dcfe4e8918209c4b904d0640ef6c1464
parent9ef02702cebc0de136384f0b7dc9d19aff13f27b

`updateFrom*` functions no longer require an arena


1 files changed, 115 insertions(+), 71 deletions(-)

lib/std/zon/parse.zig+115-71
...@@ -42,6 +42,7 @@ pub const FromOptions = struct {...@@ -42,6 +42,7 @@ pub const FromOptions = struct {
42 .ignore_unknown_fields = self.ignore_unknown_fields,42 .ignore_unknown_fields = self.ignore_unknown_fields,
43 .ignore_missing_fields = false,43 .ignore_missing_fields = false,
44 .free_on_error = self.free_on_error,44 .free_on_error = self.free_on_error,
45 .free_on_write = false,
45 };46 };
46 }47 }
47};48};
...@@ -50,12 +51,17 @@ pub const FromOptions = struct {...@@ -50,12 +51,17 @@ pub const FromOptions = struct {
50pub const UpdateFromOptions = struct {51pub const UpdateFromOptions = struct {
51 /// If true, unknown fields do not error.52 /// If true, unknown fields do not error.
52 ignore_unknown_fields: bool = false,53 ignore_unknown_fields: bool = false,
54 /// If true, the old values of overriden fields are freed. You may want to turn this off if you
55 /// are updating a value that shouldn't be freed e.g. because it contains Zig string literals.
56 /// In this case, you can use arena allocation.
57 free_on_write: bool = true,
5358
54 fn toParserOptions(self: UpdateFromOptions) Parser.Options {59 fn toParserOptions(self: UpdateFromOptions) Parser.Options {
55 return .{60 return .{
56 .ignore_unknown_fields = self.ignore_unknown_fields,61 .ignore_unknown_fields = self.ignore_unknown_fields,
57 .ignore_missing_fields = true,62 .ignore_missing_fields = true,
58 .free_on_error = false,63 .free_on_error = false,
64 .free_on_write = true,
59 };65 };
60 }66 }
61};67};
...@@ -313,7 +319,8 @@ pub fn fromSlice(...@@ -313,7 +319,8 @@ pub fn fromSlice(
313}319}
314320
315/// Similar to `fromSlice`, but updates an existing value `current`. Fields not specified by ZON are321/// Similar to `fromSlice`, but updates an existing value `current`. Fields not specified by ZON are
316/// left at their current values. Pointers are replaced with new values not mutated in place.322/// left at their current values. Pointers are replaced with new values not mutated in place. On
323/// failure, values that were updated prior to the failure are left updated.
317pub fn updateFromSlice(324pub fn updateFromSlice(
318 T: type,325 T: type,
319 gpa: Allocator,326 gpa: Allocator,
...@@ -340,39 +347,39 @@ pub fn fromSliceAlloc(...@@ -340,39 +347,39 @@ pub fn fromSliceAlloc(
340 return result;347 return result;
341}348}
342349
343/// Like updateFromSlice`, but the result may contain pointers. Requires an arena for cleanup.350/// Like updateFromSlice`, but the result may contain pointers.
344pub fn updateFromSliceAlloc(351pub fn updateFromSliceAlloc(
345 T: type,352 T: type,
346 arena: Allocator,353 gpa: Allocator,
347 current: *T,354 current: *T,
348 source: [:0]const u8,355 source: [:0]const u8,
349 diag: ?*Diagnostics,356 diag: ?*Diagnostics,
350 options: UpdateFromOptions,357 options: UpdateFromOptions,
351) error{ OutOfMemory, ParseZon }!void {358) error{ OutOfMemory, ParseZon }!void {
352 try parseSliceAlloc(T, current, arena, source, diag, options.toParserOptions());359 try parseSliceAlloc(T, current, gpa, source, diag, options.toParserOptions());
353}360}
354361
355fn parseSliceAlloc(362fn parseSliceAlloc(
356 T: type,363 T: type,
357 current: *T,364 current: *T,
358 arena: Allocator,365 gpa: Allocator,
359 source: [:0]const u8,366 source: [:0]const u8,
360 diag: ?*Diagnostics,367 diag: ?*Diagnostics,
361 options: Parser.Options,368 options: Parser.Options,
362) error{ OutOfMemory, ParseZon }!void {369) error{ OutOfMemory, ParseZon }!void {
363 if (diag) |s| s.assertEmpty();370 if (diag) |s| s.assertEmpty();
364371
365 var ast = try std.zig.Ast.parse(arena, source, .{ .mode = .zon });372 var ast = try std.zig.Ast.parse(gpa, source, .{ .mode = .zon });
366 defer if (diag == null) ast.deinit(arena);373 defer if (diag == null) ast.deinit(gpa);
367 if (diag) |s| s.ast = ast;374 if (diag) |s| s.ast = ast;
368375
369 // If there's no diagnostics, Zoir exists for the lifetime of this function. If there is a376 // If there's no diagnostics, Zoir exists for the lifetime of this function. If there is a
370 // diagnostics, ownership is transferred to diagnostics.377 // diagnostics, ownership is transferred to diagnostics.
371 var zoir = try ZonGen.generate(arena, ast, .{ .parse_str_lits = false });378 var zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
372 defer if (diag == null) zoir.deinit(arena);379 defer if (diag == null) zoir.deinit(gpa);
373380
374 if (diag) |s| s.* = .{};381 if (diag) |s| s.* = .{};
375 try parseZoirAlloc(T, arena, current, ast, zoir, diag, options);382 try parseZoirAlloc(T, gpa, current, ast, zoir, diag, options);
376}383}
377384
378/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.385/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.
...@@ -440,14 +447,14 @@ pub fn fromZoirAlloc(...@@ -440,14 +447,14 @@ pub fn fromZoirAlloc(
440/// Like updateSliceAlloc`, but operates on `Zoir` instead of ZON source.447/// Like updateSliceAlloc`, but operates on `Zoir` instead of ZON source.
441pub fn updateFromZoirAlloc(448pub fn updateFromZoirAlloc(
442 T: type,449 T: type,
443 arena: Allocator,450 gpa: Allocator,
444 current: *T,451 current: *T,
445 ast: Ast,452 ast: Ast,
446 zoir: Zoir,453 zoir: Zoir,
447 diag: ?*Diagnostics,454 diag: ?*Diagnostics,
448 options: UpdateFromOptions,455 options: UpdateFromOptions,
449) error{ OutOfMemory, ParseZon }!void {456) error{ OutOfMemory, ParseZon }!void {
450 try parseZoirAlloc(T, arena, current, ast, zoir, diag, options.toParserOptions());457 try parseZoirAlloc(T, gpa, current, ast, zoir, diag, options.toParserOptions());
451}458}
452459
453fn parseZoirAlloc(460fn parseZoirAlloc(
...@@ -534,7 +541,7 @@ pub fn fromZoirNodeAlloc(...@@ -534,7 +541,7 @@ pub fn fromZoirNodeAlloc(
534/// Like `updateZoirNodeAlloc`, but the parse starts at `node` instead of root.541/// Like `updateZoirNodeAlloc`, but the parse starts at `node` instead of root.
535pub fn updateFromZoirNodeAlloc(542pub fn updateFromZoirNodeAlloc(
536 T: type,543 T: type,
537 arena: Allocator,544 gpa: Allocator,
538 current: *T,545 current: *T,
539 ast: Ast,546 ast: Ast,
540 zoir: Zoir,547 zoir: Zoir,
...@@ -542,7 +549,7 @@ pub fn updateFromZoirNodeAlloc(...@@ -542,7 +549,7 @@ pub fn updateFromZoirNodeAlloc(
542 diag: ?*Diagnostics,549 diag: ?*Diagnostics,
543 options: UpdateFromOptions,550 options: UpdateFromOptions,
544) error{ OutOfMemory, ParseZon }!void {551) error{ OutOfMemory, ParseZon }!void {
545 return parseZoirNodeAlloc(T, arena, current, ast, zoir, node, diag, options.toParserOptions());552 return parseZoirNodeAlloc(T, gpa, current, ast, zoir, node, diag, options.toParserOptions());
546}553}
547554
548fn parseZoirNodeAlloc(555fn parseZoirNodeAlloc(
...@@ -667,6 +674,7 @@ const Parser = struct {...@@ -667,6 +674,7 @@ const Parser = struct {
667 pub const Options = struct {674 pub const Options = struct {
668 ignore_unknown_fields: bool,675 ignore_unknown_fields: bool,
669 free_on_error: bool,676 free_on_error: bool,
677 free_on_write: bool,
670 ignore_missing_fields: bool,678 ignore_missing_fields: bool,
671 };679 };
672680
...@@ -687,21 +695,22 @@ const Parser = struct {...@@ -687,21 +695,22 @@ const Parser = struct {
687 out: anytype,695 out: anytype,
688 ) ParseExprInnerError!void {696 ) ParseExprInnerError!void {
689 if (@TypeOf(out.*) == Zoir.Node.Index) {697 if (@TypeOf(out.*) == Zoir.Node.Index) {
690 out.* = node;698 self.write(out, node);
691 return;699 return;
692 }700 }
693701
694 switch (@typeInfo(@TypeOf(out.*))) {702 switch (@typeInfo(@TypeOf(out.*))) {
695 .optional => |optional| if (node.get(self.zoir) == .null) {703 .optional => |optional| if (node.get(self.zoir) == .null) {
696 out.* = null;704 self.write(out, null);
697 } else {705 } else {
698 out.* = @as(optional.child, undefined); // Make non-null706 var new: optional.child = undefined;
699 try self.parseExprInnerInto(node, &out.*.?); // Parse value into non-null pointer707 try self.parseExprInnerInto(node, &new);
708 self.write(out, new);
700 },709 },
701 .bool => out.* = try self.parseBool(node),710 .bool => self.write(out, try self.parseBool(node)),
702 .int => out.* = try self.parseInt(@TypeOf(out.*), node),711 .int => self.write(out, try self.parseInt(@TypeOf(out.*), node)),
703 .float => out.* = try self.parseFloat(@TypeOf(out.*), node),712 .float => self.write(out, try self.parseFloat(@TypeOf(out.*), node)),
704 .@"enum" => out.* = try self.parseEnumLiteral(@TypeOf(out.*), node),713 .@"enum" => self.write(out, try self.parseEnumLiteral(@TypeOf(out.*), node)),
705 .pointer => |pointer| switch (pointer.size) {714 .pointer => |pointer| switch (pointer.size) {
706 .one => {715 .one => {
707 const slice = try self.gpa.alignedAlloc(716 const slice = try self.gpa.alignedAlloc(
...@@ -710,13 +719,23 @@ const Parser = struct {...@@ -710,13 +719,23 @@ const Parser = struct {
710 1,719 1,
711 );720 );
712 errdefer self.gpa.free(slice);721 errdefer self.gpa.free(slice);
713 const ptr = &slice[0];722 const new = &slice[0];
714 self.pointer_depth += 1;723 {
715 defer self.pointer_depth -= 1;724 self.pointer_depth += 1;
716 try self.parseExprInnerInto(node, ptr);725 defer self.pointer_depth -= 1;
717 out.* = ptr;726 try self.parseExprInnerInto(node, new);
727 }
728 self.write(out, new);
729 },
730 .slice => {
731 const new = b: {
732 self.pointer_depth += 1;
733 defer self.pointer_depth -= 1;
734 const new = try self.parseSlicePointer(@TypeOf(out.*), node);
735 break :b new;
736 };
737 self.write(out, new);
718 },738 },
719 .slice => out.* = try self.parseSlicePointer(@TypeOf(out.*), node),
720 else => comptime unreachable,739 else => comptime unreachable,
721 },740 },
722 .array => try self.parseArrayInto(node, out),741 .array => try self.parseArrayInto(node, out),
...@@ -994,7 +1013,7 @@ const Parser = struct {...@@ -994,7 +1013,7 @@ const Parser = struct {
994 const vector = @typeInfo(@TypeOf(out.*)).vector;1013 const vector = @typeInfo(@TypeOf(out.*)).vector;
995 var array: [vector.len]vector.child = undefined;1014 var array: [vector.len]vector.child = undefined;
996 try self.parseArrayInto(node, &array);1015 try self.parseArrayInto(node, &array);
997 out.* = array;1016 self.write(out, array);
998 }1017 }
9991018
1000 fn parseStructInto(self: *@This(), node: Zoir.Node.Index, out: anytype) !void {1019 fn parseStructInto(self: *@This(), node: Zoir.Node.Index, out: anytype) !void {
...@@ -1166,7 +1185,7 @@ const Parser = struct {...@@ -1166,7 +1185,7 @@ const Parser = struct {
1166 return self.failNode(node, "expected union");1185 return self.failNode(node, "expected union");
11671186
1168 // Instantiate the union1187 // Instantiate the union
1169 out.* = @unionInit(@TypeOf(out.*), @"union".field_names[i], {});1188 self.write(out, @unionInit(@TypeOf(out.*), @"union".field_names[i], {}));
1170 },1189 },
1171 else => unreachable, // Can't be out of bounds1190 else => unreachable, // Can't be out of bounds
1172 }1191 }
...@@ -1188,7 +1207,7 @@ const Parser = struct {...@@ -1188,7 +1207,7 @@ const Parser = struct {
1188 if (@"union".field_types[i] == void) {1207 if (@"union".field_types[i] == void) {
1189 return self.failNode(field_val, "expected type 'void'");1208 return self.failNode(field_val, "expected type 'void'");
1190 } else {1209 } else {
1191 out.* = @unionInit(@TypeOf(out.*), @"union".field_names[i], undefined);1210 self.write(out, @unionInit(@TypeOf(out.*), @"union".field_names[i], undefined));
1192 try self.parseExprInto(field_val, &@field(out.*, @"union".field_names[i]));1211 try self.parseExprInto(field_val, &@field(out.*, @"union".field_names[i]));
1193 }1212 }
1194 },1213 },
...@@ -1363,6 +1382,16 @@ const Parser = struct {...@@ -1363,6 +1382,16 @@ const Parser = struct {
1363 .note = null,1382 .note = null,
1364 });1383 });
1365 }1384 }
1385
1386 /// Write to out, freeing the old value first if necessary.
1387 fn write(self: *@This(), out: anytype, new: @TypeOf(out.*)) void {
1388 if (@typeInfo(@TypeOf(out)) == .pointer) {
1389 if (self.options.free_on_write and self.pointer_depth == 0) {
1390 free(self.gpa, out.*);
1391 }
1392 }
1393 out.* = new;
1394 }
1366};1395};
13671396
1368fn intFromFloatExact(T: type, value: anytype) ?T {1397fn intFromFloatExact(T: type, value: anytype) ?T {
...@@ -3785,12 +3814,8 @@ test "std.zon aligned pointers" {...@@ -3785,12 +3814,8 @@ test "std.zon aligned pointers" {
3785 try std.testing.expectEqualDeep(expected.inner, found.inner);3814 try std.testing.expectEqualDeep(expected.inner, found.inner);
3786}3815}
37873816
3788test "std.zon update semantics" {3817test "std.zon update" {
3789 // Test that the update logic works as expected3818 const gpa = std.testing.allocator;
3790
3791 var arena_allocator: std.heap.ArenaAllocator = .init(std.testing.allocator);
3792 defer arena_allocator.deinit();
3793 const arena = arena_allocator.allocator();
37943819
3795 const Vector = struct { x: f32, y: f32, z: f32 };3820 const Vector = struct { x: f32, y: f32, z: f32 };
3796 const MyStruct = struct {3821 const MyStruct = struct {
...@@ -3802,42 +3827,58 @@ test "std.zon update semantics" {...@@ -3802,42 +3827,58 @@ test "std.zon update semantics" {
3802 },3827 },
3803 ptr: *Vector,3828 ptr: *Vector,
3804 optional: ?u32 = null,3829 optional: ?u32 = null,
3805 str: []const u8 = "hello, world",3830 str: []const u8,
3806 };3831 };
38073832
3808 var v: Vector = .{ .x = 1, .y = 2, .z = 3 };
3809 var expected: MyStruct = .{3833 var expected: MyStruct = .{
3810 .foo = 10,3834 .foo = 10,
3811 .bar = true,3835 .bar = true,
3812 .baz = .{ .a = .{ 1, 2 }, .b = .c },3836 .baz = .{ .a = .{ 1, 2 }, .b = .c },
3813 .ptr = &v,3837 .ptr = b: {
3838 const v = gpa.create(Vector) catch @panic("oom");
3839 v.* = .{ .x = 1, .y = 2, .z = 3 };
3840 break :b v;
3841 },
3842 .str = gpa.dupe(u8, "hello, world") catch @panic("oom"),
3843 };
3844 defer free(gpa, expected);
3845 var found: MyStruct = .{
3846 .foo = 10,
3847 .bar = true,
3848 .baz = .{ .a = .{ 1, 2 }, .b = .c },
3849 .ptr = b: {
3850 const v = gpa.create(Vector) catch @panic("oom");
3851 v.* = .{ .x = 1, .y = 2, .z = 3 };
3852 break :b v;
3853 },
3854 .str = gpa.dupe(u8, "hello, world") catch @panic("oom"),
3814 };3855 };
3815 var found = expected;3856 defer free(gpa, found);
38163857
3817 try updateFromSliceAlloc(3858 try updateFromSliceAlloc(
3818 MyStruct,3859 MyStruct,
3819 arena,3860 gpa,
3820 &found,3861 &found,
3821 ".{}",3862 ".{}",
3822 null,3863 null,
3823 .{},3864 .{},
3824 );3865 );
3825 try std.testing.expectEqual(expected, found);3866 try std.testing.expectEqualDeep(expected, found);
38263867
3827 try updateFromSliceAlloc(3868 try updateFromSliceAlloc(
3828 MyStruct,3869 MyStruct,
3829 arena,3870 gpa,
3830 &found,3871 &found,
3831 ".{ .bar = false }",3872 ".{ .bar = false }",
3832 null,3873 null,
3833 .{},3874 .{},
3834 );3875 );
3835 expected.bar = false;3876 expected.bar = false;
3836 try std.testing.expectEqual(expected, found);3877 try std.testing.expectEqualDeep(expected, found);
38373878
3838 try updateFromSliceAlloc(3879 try updateFromSliceAlloc(
3839 MyStruct,3880 MyStruct,
3840 arena,3881 gpa,
3841 &found,3882 &found,
3842 ".{ .baz = .{ .a = .{ 2, 4 } } }",3883 ".{ .baz = .{ .a = .{ 2, 4 } } }",
3843 null,3884 null,
...@@ -3845,11 +3886,11 @@ test "std.zon update semantics" {...@@ -3845,11 +3886,11 @@ test "std.zon update semantics" {
3845 );3886 );
3846 expected.baz.a[0] = 2;3887 expected.baz.a[0] = 2;
3847 expected.baz.a[1] = 4;3888 expected.baz.a[1] = 4;
3848 try std.testing.expectEqual(expected, found);3889 try std.testing.expectEqualDeep(expected, found);
38493890
3850 try updateFromSliceAlloc(3891 try updateFromSliceAlloc(
3851 MyStruct,3892 MyStruct,
3852 arena,3893 gpa,
3853 &found,3894 &found,
3854 ".{ .foo = 11, .baz = .{ .b = .d } }",3895 ".{ .foo = 11, .baz = .{ .b = .d } }",
3855 null,3896 null,
...@@ -3857,33 +3898,33 @@ test "std.zon update semantics" {...@@ -3857,33 +3898,33 @@ test "std.zon update semantics" {
3857 );3898 );
3858 expected.foo = 11;3899 expected.foo = 11;
3859 expected.baz.b = .d;3900 expected.baz.b = .d;
3860 try std.testing.expectEqual(expected, found);3901 try std.testing.expectEqualDeep(expected, found);
38613902
3862 try updateFromSliceAlloc(3903 try updateFromSliceAlloc(
3863 MyStruct,3904 MyStruct,
3864 arena,3905 gpa,
3865 &found,3906 &found,
3866 ".{ .optional = 10 }",3907 ".{ .optional = 10 }",
3867 null,3908 null,
3868 .{},3909 .{},
3869 );3910 );
3870 expected.optional = 10;3911 expected.optional = 10;
3871 try std.testing.expectEqual(expected, found);3912 try std.testing.expectEqualDeep(expected, found);
38723913
3873 try updateFromSliceAlloc(3914 try updateFromSliceAlloc(
3874 MyStruct,3915 MyStruct,
3875 arena,3916 gpa,
3876 &found,3917 &found,
3877 ".{ .optional = null }",3918 ".{ .optional = null }",
3878 null,3919 null,
3879 .{},3920 .{},
3880 );3921 );
3881 expected.optional = null;3922 expected.optional = null;
3882 try std.testing.expectEqual(expected, found);3923 try std.testing.expectEqualDeep(expected, found);
38833924
3884 try updateFromSliceAlloc(3925 try updateFromSliceAlloc(
3885 MyStruct,3926 MyStruct,
3886 arena,3927 gpa,
3887 &found,3928 &found,
3888 ".{ .ptr = .{ .x = 10, .y = 20, .z = 30 } }",3929 ".{ .ptr = .{ .x = 10, .y = 20, .z = 30 } }",
3889 null,3930 null,
...@@ -3896,13 +3937,14 @@ test "std.zon update semantics" {...@@ -3896,13 +3937,14 @@ test "std.zon update semantics" {
38963937
3897 try updateFromSliceAlloc(3938 try updateFromSliceAlloc(
3898 MyStruct,3939 MyStruct,
3899 arena,3940 gpa,
3900 &found,3941 &found,
3901 ".{ .str = \"foo\" }",3942 ".{ .str = \"foo\" }",
3902 null,3943 null,
3903 .{},3944 .{},
3904 );3945 );
3905 expected.str = "foo";3946 gpa.free(expected.str);
3947 expected.str = gpa.dupe(u8, "foo") catch @panic("oom");
3906 try std.testing.expectEqualDeep(expected, found);3948 try std.testing.expectEqualDeep(expected, found);
3907}3949}
39083950
...@@ -3910,9 +3952,7 @@ test "std.zon variants" {...@@ -3910,9 +3952,7 @@ test "std.zon variants" {
3910 // Just a smoke test, we don't need to test each variant thoroughly because they all call into3952 // Just a smoke test, we don't need to test each variant thoroughly because they all call into
3911 // the same code.3953 // the same code.
39123954
3913 var arena_allocator: std.heap.ArenaAllocator = .init(std.testing.allocator);3955 const gpa = std.testing.allocator;
3914 defer arena_allocator.deinit();
3915 const arena = arena_allocator.allocator();
39163956
3917 const Struct = struct { a: u32, b: u32 };3957 const Struct = struct { a: u32, b: u32 };
3918 const start: Struct = .{ .a = 10, .b = 20 };3958 const start: Struct = .{ .a = 10, .b = 20 };
...@@ -3920,15 +3960,17 @@ test "std.zon variants" {...@@ -3920,15 +3960,17 @@ test "std.zon variants" {
39203960
3921 // Update3961 // Update
3922 {3962 {
3923 const ast = try std.zig.Ast.parse(arena, ".{ .a = 100 }", .{ .mode = .zon });3963 var ast = try std.zig.Ast.parse(gpa, ".{ .a = 100 }", .{ .mode = .zon });
3924 const zoir = try ZonGen.generate(arena, ast, .{ .parse_str_lits = false });3964 defer ast.deinit(gpa);
3965 const zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
3966 defer zoir.deinit(gpa);
39253967
3926 var curr = start;3968 var curr = start;
3927 try updateFromSlice(Struct, arena, &curr, ".{ .a = 100 }", null, .{});3969 try updateFromSlice(Struct, gpa, &curr, ".{ .a = 100 }", null, .{});
3928 try std.testing.expectEqual(end, curr);3970 try std.testing.expectEqual(end, curr);
39293971
3930 curr = start;3972 curr = start;
3931 try updateFromSliceAlloc(Struct, arena, &curr, ".{ .a = 100 }", null, .{});3973 try updateFromSliceAlloc(Struct, gpa, &curr, ".{ .a = 100 }", null, .{});
3932 try std.testing.expectEqual(end, curr);3974 try std.testing.expectEqual(end, curr);
39333975
3934 curr = start;3976 curr = start;
...@@ -3936,7 +3978,7 @@ test "std.zon variants" {...@@ -3936,7 +3978,7 @@ test "std.zon variants" {
3936 try std.testing.expectEqual(end, curr);3978 try std.testing.expectEqual(end, curr);
39373979
3938 curr = start;3980 curr = start;
3939 try updateFromZoirAlloc(Struct, arena, &curr, ast, zoir, null, .{});3981 try updateFromZoirAlloc(Struct, gpa, &curr, ast, zoir, null, .{});
3940 try std.testing.expectEqual(end, curr);3982 try std.testing.expectEqual(end, curr);
39413983
3942 curr = start;3984 curr = start;
...@@ -3944,29 +3986,31 @@ test "std.zon variants" {...@@ -3944,29 +3986,31 @@ test "std.zon variants" {
3944 try std.testing.expectEqual(end, curr);3986 try std.testing.expectEqual(end, curr);
39453987
3946 curr = start;3988 curr = start;
3947 try updateFromZoirNodeAlloc(Struct, arena, &curr, ast, zoir, .root, null, .{});3989 try updateFromZoirNodeAlloc(Struct, gpa, &curr, ast, zoir, .root, null, .{});
3948 try std.testing.expectEqual(end, curr);3990 try std.testing.expectEqual(end, curr);
3949 }3991 }
39503992
3951 // From3993 // From
3952 {3994 {
3953 const ast = try std.zig.Ast.parse(arena, ".{ .a = 100, .b = 20 }", .{ .mode = .zon });3995 var ast = try std.zig.Ast.parse(gpa, ".{ .a = 100, .b = 20 }", .{ .mode = .zon });
3954 const zoir = try ZonGen.generate(arena, ast, .{ .parse_str_lits = false });3996 defer ast.deinit(gpa);
3997 const zoir = try ZonGen.generate(gpa, ast, .{ .parse_str_lits = false });
3998 defer zoir.deinit(gpa);
39553999
3956 try std.testing.expectEqual(4000 try std.testing.expectEqual(
3957 end,4001 end,
3958 try fromSlice(Struct, arena, ".{ .a = 100, .b = 20 }", null, .{}),4002 try fromSlice(Struct, gpa, ".{ .a = 100, .b = 20 }", null, .{}),
3959 );4003 );
3960 try std.testing.expectEqual(4004 try std.testing.expectEqual(
3961 end,4005 end,
3962 try fromSliceAlloc(Struct, arena, ".{ .a = 100, .b = 20 }", null, .{}),4006 try fromSliceAlloc(Struct, gpa, ".{ .a = 100, .b = 20 }", null, .{}),
3963 );4007 );
3964 try std.testing.expectEqual(4008 try std.testing.expectEqual(
3965 try fromZoir(Struct, ast, zoir, null, .{}),4009 try fromZoir(Struct, ast, zoir, null, .{}),
3966 end,4010 end,
3967 );4011 );
3968 try std.testing.expectEqual(4012 try std.testing.expectEqual(
3969 try fromZoirAlloc(Struct, arena, ast, zoir, null, .{}),4013 try fromZoirAlloc(Struct, gpa, ast, zoir, null, .{}),
3970 end,4014 end,
3971 );4015 );
3972 try std.testing.expectEqual(4016 try std.testing.expectEqual(
...@@ -3974,7 +4018,7 @@ test "std.zon variants" {...@@ -3974,7 +4018,7 @@ test "std.zon variants" {
3974 end,4018 end,
3975 );4019 );
3976 try std.testing.expectEqual(4020 try std.testing.expectEqual(
3977 try fromZoirNodeAlloc(Struct, arena, ast, zoir, .root, null, .{}),4021 try fromZoirNodeAlloc(Struct, gpa, ast, zoir, .root, null, .{}),
3978 end,4022 end,
3979 );4023 );
3980 }4024 }