commit 996b4118097c747e65ef1127091f7e48a54bfafc (tree)
parent 4cbc03dce31b63818da1fb47f959b70708683443
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 20 May 2026 20:38:05 -0700
Configuration: more type safety for adding data
erased method still exists for when the result will be converted to an
int anyway.
Diffstat:
2 files changed, 83 insertions(+), 78 deletions(-)
diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig
@@ -166,11 +166,11 @@ const Serialize = struct {
const wc = s.wc;
const gop = try s.package_map.getOrPut(arena, b);
if (!gop.found_existing) {
- gop.value_ptr.* = @enumFromInt(try wc.addExtra(@as(Configuration.Package, .{
+ gop.value_ptr.* = try wc.addExtra(Configuration.Package, .{
.hash = try wc.addString(b.pkg_hash),
.dep_prefix = try wc.addString(b.dep_prefix),
.root_path = try wc.addString(try b.root.toString(arena)),
- })));
+ });
}
return gop.value_ptr.*;
}
@@ -180,38 +180,38 @@ const Serialize = struct {
return @enumFromInt(switch (lp orelse return .none) {
.src_path => |src_path| i: {
const sub_path = try wc.addString(src_path.sub_path);
- break :i try wc.addExtra(@as(Configuration.LazyPath.SourcePath, .{
+ break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
.owner = try s.builderToPackage(src_path.owner),
.sub_path = sub_path,
- }));
+ });
},
.generated => |generated| i: {
const sub_path = try wc.addString(generated.sub_path);
- break :i try wc.addExtra(@as(Configuration.LazyPath.Generated, .{
+ break :i try wc.addExtraErased(Configuration.LazyPath.Generated, .{
.flags = .{ .up = @intCast(generated.up) },
.index = generated.index,
.sub_path = sub_path,
- }));
+ });
},
.cwd_relative => |cwd_relative_sub_path| i: {
const sub_path = try wc.addString(cwd_relative_sub_path);
- break :i try wc.addExtra(@as(Configuration.LazyPath.Relative, .{
+ break :i try wc.addExtraErased(Configuration.LazyPath.Relative, .{
.flags = .{ .base = .cwd },
.sub_path = sub_path,
- }));
+ });
},
.relative => |relative| i: {
- break :i try wc.addExtra(@as(Configuration.LazyPath.Relative, .{
+ break :i try wc.addExtraErased(Configuration.LazyPath.Relative, .{
.flags = .{ .base = relative.base },
.sub_path = relative.sub_path,
- }));
+ });
},
.dependency => |dependency| i: {
const sub_path = try wc.addString(dependency.sub_path);
- break :i try wc.addExtra(@as(Configuration.LazyPath.SourcePath, .{
+ break :i try wc.addExtraErased(Configuration.LazyPath.SourcePath, .{
.owner = try s.builderToPackage(dependency.dependency.builder),
.sub_path = sub_path,
- }));
+ });
},
});
}
@@ -249,21 +249,21 @@ const Serialize = struct {
fn addCSourceFile(s: *Serialize, csf: *const std.Build.Module.CSourceFile) !Configuration.CSourceFile.Index {
const wc = s.wc;
const args = try initStringList(s, csf.flags);
- return @enumFromInt(try wc.addExtra(@as(Configuration.CSourceFile, .{
+ return try wc.addExtra(Configuration.CSourceFile, .{
.flags = .{
.args_len = @intCast(args.len),
.lang = .init(csf.language),
},
.file = try addLazyPath(s, csf.file),
.args = .{ .slice = args },
- })));
+ });
}
fn addCSourceFiles(s: *Serialize, csf: *const std.Build.Module.CSourceFiles) !Configuration.CSourceFiles.Index {
const wc = s.wc;
const sub_paths = try initStringList(s, csf.files);
const args = try initStringList(s, csf.flags);
- return @enumFromInt(try wc.addExtra(@as(Configuration.CSourceFiles, .{
+ return try wc.addExtra(Configuration.CSourceFiles, .{
.flags = .{
.args_len = @intCast(args.len),
.lang = .init(csf.language),
@@ -271,14 +271,14 @@ const Serialize = struct {
.root = try addLazyPath(s, csf.root),
.sub_paths = .{ .slice = sub_paths },
.args = .{ .slice = args },
- })));
+ });
}
fn addRcSourceFile(s: *Serialize, rsf: *const std.Build.Module.RcSourceFile) !Configuration.RcSourceFile.Index {
const wc = s.wc;
const include_paths = try initLazyPathList(s, rsf.include_paths);
const args = try initStringList(s, rsf.flags);
- return @enumFromInt(try wc.addExtra(@as(Configuration.RcSourceFile, .{
+ return try wc.addExtra(Configuration.RcSourceFile, .{
.flags = .{
.args_len = @intCast(args.len),
.include_paths = include_paths.len != 0,
@@ -286,7 +286,7 @@ const Serialize = struct {
.file = try addLazyPath(s, rsf.file),
.include_paths = .{ .slice = include_paths },
.args = .{ .slice = args },
- })));
+ });
}
fn addEnvironMap(s: *Serialize, opt_map: ?*std.process.Environ.Map) !?Configuration.EnvironMap.Index {
@@ -302,7 +302,7 @@ const Serialize = struct {
const wc = s.wc;
const result = try s.arena.alloc(Configuration.Step.Run.Arg.Index, args.len);
for (result, args) |*dest, src| {
- dest.* = @enumFromInt(try wc.addExtra(@as(Configuration.Step.Run.Arg, switch (src) {
+ dest.* = try wc.addExtra(Configuration.Step.Run.Arg, switch (src) {
.artifact => |a| .{
.flags = .{
.tag = .artifact,
@@ -492,7 +492,7 @@ const Serialize = struct {
.generated = .{ .value = null },
.target_query = .{ .value = a.target_query.unwrap() },
},
- })));
+ });
}
return result;
}
@@ -580,7 +580,7 @@ const Serialize = struct {
const c_macros = try initStringList(s, m.c_macros.items);
const export_symbol_names = try initStringList(s, m.export_symbol_names);
- const module_index: Configuration.Module.Index = @enumFromInt(try wc.addExtra(@as(Configuration.Module, .{
+ const module_index: Configuration.Module.Index = try wc.addExtra(Configuration.Module, .{
.flags = .{
.optimize = .init(m.optimize),
.strip = .init(m.strip),
@@ -622,7 +622,7 @@ const Serialize = struct {
.rpaths = .init(rpaths),
.link_objects = .init(link_objects),
.frameworks = .{ .slice = frameworks },
- })));
+ });
// The import table is the only place that modules can form dependency
// loops. Therefore, we populate the module indexes only after adding
@@ -699,12 +699,12 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.owner = try s.builderToPackage(step.owner),
.deps = deps,
.max_rss = .fromBytes(step.max_rss),
- .extended = switch (step.tag) {
+ .extended = @enumFromInt(switch (step.tag) {
.top_level => e: {
const top_level: *Step.TopLevel = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.TopLevel, .{
+ break :e try wc.addExtraErased(Configuration.Step.TopLevel, .{
.description = try wc.addString(top_level.description),
- })));
+ });
},
.compile => e: {
const c: *Step.Compile = @fieldParentPtr("step", step);
@@ -712,14 +712,14 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
const installed_headers: []u32 = try arena.alloc(u32, c.installed_headers.items.len);
for (installed_headers, c.installed_headers.items) |*dst, src| switch (src) {
.file => |file| {
- dst.* = try wc.addExtra(@as(Configuration.Step.Compile.InstalledHeader.File, .{
+ dst.* = try wc.addExtraErased(Configuration.Step.Compile.InstalledHeader.File, .{
.source = try s.addLazyPath(file.source),
.dest_sub_path = try wc.addString(file.dest_rel_path),
- }));
+ });
},
.directory => |directory| {
const include_extensions = directory.options.include_extensions orelse &.{};
- dst.* = try wc.addExtra(@as(Configuration.Step.Compile.InstalledHeader.Directory, .{
+ dst.* = try wc.addExtraErased(Configuration.Step.Compile.InstalledHeader.Directory, .{
.flags = .{
.include_extensions = include_extensions.len != 0,
.exclude_extensions = directory.options.exclude_extensions.len != 0,
@@ -728,11 +728,11 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.dest_sub_path = try wc.addString(directory.dest_rel_path),
.exclude_extensions = .{ .slice = try s.initStringList(directory.options.exclude_extensions) },
.include_extensions = .{ .slice = try s.initStringList(include_extensions) },
- }));
+ });
},
};
- const extra_index = try wc.addExtra(@as(Configuration.Step.Compile, .{
+ break :e try wc.addExtraErased(Configuration.Step.Compile, .{
.flags = .{
.filters_len = c.filters.len != 0,
.exec_cmd_args_len = exec_cmd_args.len != 0,
@@ -891,13 +891,11 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.generated_llvm_bc = .{ .value = c.generated_llvm_bc.unwrap() },
.generated_llvm_ir = .{ .value = c.generated_llvm_ir.unwrap() },
.generated_h = .{ .value = c.generated_h.unwrap() },
- }));
-
- break :e @enumFromInt(extra_index);
+ });
},
.install_artifact => e: {
const ia: *Step.InstallArtifact = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallArtifact, .{
+ break :e try wc.addExtraErased(Configuration.Step.InstallArtifact, .{
.flags = .{
.dylib_symlinks = ia.dylib_symlinks,
.bin_dir = ia.dest_dir != null,
@@ -911,15 +909,15 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.pdb_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.pdb_dir) },
.h_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.h_dir) },
.bin_sub_path = .{ .value = try s.addOptionalString(ia.dest_sub_path) },
- })));
+ });
},
.install_file => e: {
const sif: *Step.InstallFile = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallFile, .{
+ break :e try wc.addExtraErased(Configuration.Step.InstallFile, .{
.source = try s.addLazyPath(sif.source),
.dest_dir = try addInstallDir(wc, sif.dir),
.dest_sub_path = try wc.addString(sif.dest_rel_path),
- })));
+ });
},
.install_dir => e: {
const sid: *Step.InstallDir = @fieldParentPtr("step", step);
@@ -928,7 +926,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
else
null;
const include_extensions = sid.options.include_extensions orelse &.{};
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallDir, .{
+ break :e try wc.addExtraErased(Configuration.Step.InstallDir, .{
.flags = .{
.dest_sub_path = dest_sub_path != null,
.exclude_extensions = sid.options.exclude_extensions.len != 0,
@@ -942,18 +940,18 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.exclude_extensions = .{ .slice = try s.initStringList(sid.options.exclude_extensions) },
.include_extensions = .{ .slice = try s.initStringList(include_extensions) },
.blank_extensions = .{ .slice = try s.initStringList(sid.options.blank_extensions) },
- })));
+ });
},
.fail => e: {
const sf: *Step.Fail = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.Fail, .{
+ break :e try wc.addExtraErased(Configuration.Step.Fail, .{
.msg = sf.error_msg,
- })));
+ });
},
.find_program => @panic("TODO"),
.fmt => e: {
const sf: *Step.Fmt = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.Fmt, .{
+ break :e try wc.addExtraErased(Configuration.Step.Fmt, .{
.flags = .{
.paths = sf.paths.len != 0,
.exclude_paths = sf.exclude_paths.len != 0,
@@ -961,7 +959,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
},
.paths = .{ .slice = try s.initLazyPathList(sf.paths) },
.exclude_paths = .{ .slice = try s.initLazyPathList(sf.exclude_paths) },
- })));
+ });
},
.translate_c => e: {
const tc: *Step.TranslateC = @fieldParentPtr("step", step);
@@ -969,7 +967,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
const system_libs = try arena.alloc(Configuration.SystemLib.Index, tc.system_libs.items.len);
for (system_libs, tc.system_libs.items) |*dest, *src| dest.* = try s.addSystemLib(src);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.TranslateC, .{
+ break :e try wc.addExtraErased(Configuration.Step.TranslateC, .{
.flags = .{
.include_dirs = tc.include_dirs.items.len != 0,
.system_libs = system_libs.len != 0,
@@ -983,7 +981,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.system_libs = .{ .slice = system_libs },
.c_macros = .{ .slice = tc.c_macros.items },
.target = try addOptionalResolvedTarget(wc, tc.target),
- })));
+ });
},
.write_file => e: {
const wf: *Step.WriteFile = @fieldParentPtr("step", step);
@@ -999,7 +997,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.include_extensions = src.include_extensions,
};
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.WriteFile, .{
+ break :e try wc.addExtraErased(Configuration.Step.WriteFile, .{
.flags = .{
.embeds = wf.embeds.items.len != 0,
.copies = wf.copies.items.len != 0,
@@ -1018,18 +1016,18 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.mutate => |lp| try s.addLazyPath(lp),
.whole_cached, .tmp => null,
} },
- })));
+ });
},
.update_source_files => e: {
const usf: *Step.UpdateSourceFiles = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.UpdateSourceFiles, .{
+ break :e try wc.addExtraErased(Configuration.Step.UpdateSourceFiles, .{
.flags = .{
.embeds = usf.embeds.items.len != 0,
.copies = usf.copies.items.len != 0,
},
.embeds = .{ .slice = usf.embeds.items },
.copies = .{ .slice = try s.initCopyList(usf.copies.items) },
- })));
+ });
},
.run => e: {
const run: *Step.Run = @fieldParentPtr("step", step);
@@ -1061,7 +1059,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
else => {},
}
- const extra_index = try wc.addExtra(@as(Configuration.Step.Run, .{
+ break :e try wc.addExtraErased(Configuration.Step.Run, .{
.flags = .{
.disable_zig_progress = run.disable_zig_progress,
.skip_foreign_checks = run.skip_foreign_checks,
@@ -1121,12 +1119,11 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.bytes => |bytes| .{ .bytes = try wc.addBytes(bytes) },
.lazy_path => |lp| .{ .lazy_path = try s.addLazyPath(lp) },
} },
- }));
- break :e @enumFromInt(extra_index);
+ });
},
.check_file => e: {
const cf: *Step.CheckFile = @fieldParentPtr("step", step);
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.CheckFile, .{
+ break :e try wc.addExtraErased(Configuration.Step.CheckFile, .{
.flags = .{
.expected_exact = cf.expected_exact != null,
.expected_matches = cf.expected_matches.len != 0,
@@ -1136,7 +1133,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.expected_exact = .{ .value = cf.expected_exact },
.expected_matches = .{ .slice = cf.expected_matches },
.max_bytes = .{ .value = cf.max_bytes },
- })));
+ });
},
.config_header => e: {
const ch: *Step.ConfigHeader = @fieldParentPtr("step", step);
@@ -1154,11 +1151,9 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.int => |x| switch (x) {
0 => .int_0,
1 => .int_1,
- else => @enumFromInt(try wc.addExtra(
- Configuration.Step.ConfigHeader.Value.initSigned(x),
- )),
+ else => try wc.addExtra(Configuration.Step.ConfigHeader.Value, .initSigned(x)),
},
- .ident => |x| @enumFromInt(try wc.addExtra(@as(Configuration.Step.ConfigHeader.Value, .{
+ .ident => |x| try wc.addExtra(Configuration.Step.ConfigHeader.Value, .{
.flags = .{
.tag = .ident,
.small = 0,
@@ -1167,8 +1162,8 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.u64 = .{ .value = null },
.ident = .{ .value = try wc.addString(x) },
.string = .{ .value = null },
- }))),
- .string => |x| @enumFromInt(try wc.addExtra(@as(Configuration.Step.ConfigHeader.Value, .{
+ }),
+ .string => |x| try wc.addExtra(Configuration.Step.ConfigHeader.Value, .{
.flags = .{
.tag = .string,
.small = 0,
@@ -1177,10 +1172,10 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.u64 = .{ .value = null },
.ident = .{ .value = null },
.string = .{ .value = try wc.addString(x) },
- }))),
+ }),
},
};
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.ConfigHeader, .{
+ break :e try wc.addExtraErased(Configuration.Step.ConfigHeader, .{
.flags = .{
.template_file = lazy_path != null,
.style = .init(ch.style),
@@ -1193,7 +1188,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.include_path = try wc.addString(ch.include_path),
.include_guard = .{ .value = ch.include_guard.unwrap() },
.values = .{ .slice = pairs },
- })));
+ });
},
.obj_copy => e: {
const oc: *Step.ObjCopy = @fieldParentPtr("step", step);
@@ -1217,7 +1212,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.file_path = try s.addLazyPath(src.file_path),
};
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.ObjCopy, .{
+ break :e try wc.addExtraErased(Configuration.Step.ObjCopy, .{
.flags = .{
.basename = oc.basename != .none,
.debug_file = debug_file != null,
@@ -1239,7 +1234,7 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.pad_to = .{ .value = oc.pad_to },
.add_section = .{ .slice = add_sections },
.update_section = .{ .slice = oc.update_sections.items },
- })));
+ });
},
.options => e: {
const so: *Step.Options = @fieldParentPtr("step", step);
@@ -1250,16 +1245,16 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
.path = try s.addLazyPath(src.path),
};
- break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.Options, .{
+ break :e try wc.addExtraErased(Configuration.Step.Options, .{
.flags = .{
.args = so.args.items.len != 0,
},
.generated_file = so.generated_file,
.contents = try wc.addBytes(so.contents.items),
.args = .{ .slice = args },
- })));
+ });
},
- },
+ }),
});
}
}
diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig
@@ -254,7 +254,7 @@ pub const Wip = struct {
null;
const cpu_features_add_empty = q.cpu_features_add.isEmpty();
const cpu_features_sub_empty = q.cpu_features_sub.isEmpty();
- const result_index: TargetQuery.Index = @enumFromInt(try wip.addExtra(@as(TargetQuery, .{
+ const result_index: TargetQuery.Index = try wip.addExtra(TargetQuery, .{
.flags = .{
.cpu_arch = .init(q.cpu_arch),
.cpu_model = .init(q.cpu_model),
@@ -277,7 +277,7 @@ pub const Wip = struct {
.cpu_name = .{ .value = cpu_name },
.os_version_min = .{ .u = os_version_min },
.os_version_max = .{ .u = os_version_max },
- })));
+ });
// Deduplicate.
const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{
@@ -329,7 +329,7 @@ pub const Wip = struct {
};
const dynamic_linker: ?String = if (t.dynamic_linker.get()) |dl| try wip.addString(dl) else null;
const cpu_features_add_empty = t.cpu.features.isEmpty();
- const result_index: TargetQuery.Index = @enumFromInt(try wip.addExtra(@as(TargetQuery, .{
+ const result_index = try wip.addExtra(TargetQuery, .{
.flags = .{
.cpu_arch = .init(t.cpu.arch),
.cpu_model = .explicit,
@@ -352,7 +352,7 @@ pub const Wip = struct {
.cpu_name = .{ .value = cpu_name },
.os_version_min = .{ .u = os_version_min },
.os_version_max = .{ .u = os_version_max },
- })));
+ });
// Deduplicate.
const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{
@@ -366,10 +366,16 @@ pub const Wip = struct {
}
}
- pub fn addExtra(wip: *Wip, extra: anytype) Allocator.Error!u32 {
- const extra_len = Storage.extraLen(extra);
+ pub fn addExtra(wip: *Wip, comptime T: type, v: T) Allocator.Error!T.Index {
+ const extra_len = Storage.extraLen(v);
try wip.extra.ensureUnusedCapacity(wip.gpa, extra_len);
- return addExtraAssumeCapacity(wip, extra);
+ return addExtraReserved(wip, T, v);
+ }
+
+ pub fn addExtraErased(wip: *Wip, comptime T: type, v: T) Allocator.Error!u32 {
+ const extra_len = Storage.extraLen(v);
+ try wip.extra.ensureUnusedCapacity(wip.gpa, extra_len);
+ return addExtraReservedErased(wip, T, v);
}
/// Same as `addExtra` but uses a hash map to possibly return an already
@@ -382,7 +388,7 @@ pub const Wip = struct {
try wip.dedupe_table.ensureUnusedCapacityContext(gpa, 1, @as(ExtraSlice.Context, .{
.extra = wip.extra.items,
}));
- const new_index = addExtraAssumeCapacity(wip, v);
+ const new_index = addExtraReservedErased(wip, T, v);
const len: u32 = @intCast(wip.extra.items.len - new_index);
assert(len != 0);
const gop = wip.dedupe_table.getOrPutAssumeCapacityContext(.{
@@ -398,9 +404,13 @@ pub const Wip = struct {
return @enumFromInt(new_index);
}
- pub fn addExtraAssumeCapacity(wip: *Wip, extra: anytype) u32 {
+ pub fn addExtraReserved(wip: *Wip, comptime T: type, v: T) T.Index {
+ return @enumFromInt(addExtraReservedErased(wip, T, v));
+ }
+
+ pub fn addExtraReservedErased(wip: *Wip, comptime T: type, v: T) u32 {
const result: u32 = @intCast(wip.extra.items.len);
- wip.extra.items.len = Storage.setExtra(wip.extra.allocatedSlice(), result, extra);
+ wip.extra.items.len = Storage.setExtra(wip.extra.allocatedSlice(), result, v);
return result;
}