std.builtin.Type.StructField
has the default_value
field which is of type ?*const anyopaque
. I attempted to write a simple convenience function for helping me build these:
fn buildfield(comptime name: [:0]const u8, comptime typ: type, comptime opts: anytype) Type.StructField {
comptime var default_value: ?*const anyopaque = null;
comptime var is_comptime: bool = false;
comptime var alignment: comptime_int = @alignOf(typ);
inline for (meta.fields(@TypeOf(opts))) |opt| {
if (mem.eql(u8, opt.name, "default_value")) {
default_value = @ptrCast(&@field(opts, opt.name));
} else if (mem.eql(u8, opt.name, "is_comptime")) {
is_comptime = @field(opts, opt.name);
} else if (mem.eql(u8, opt.name, "alignment")) {
alignment = @field(opts, opt.name);
} else {
@compileError("got bogus argument for buildfield option");
}
}
return Type.StructField{
.name = name,
.type = typ,
.default_value = default_value,
.is_comptime = is_comptime,
.alignment = alignment,
};
}
This was my best guess at how I should be casting the default_value
. This code may even work in some circumstances, however I suspect something is amiss. When I do, for example
const f = buildfield("testfield", i64, .{ .default_value = 1 });
and try to do anything with the result, I get
src/root.zig:62:33: error: runtime value contains reference to comptime var
std.debug.print("{any}\n", .{f});
~^~~
src/root.zig:62:33: note: comptime var pointers are not available at runtime
Clearly something is happening in my coercion of the type that it thinks may not be knowable at compile time, but I’m unsure how to resolve this. Any suggestions? Thanks!
Update: Expanding on this a bit, I seem to be having a broader problem in not understanding what happens once I start needing pointers to comptime
values. Continuing with this example, my next convenience function
fn buildstruct(comptime flds: anytype) Type.Struct {
const decls: [0]Type.Declaration = .{};
return Type.Struct{
.layout = Type.ContainerLayout.auto,
.backing_integer = null, // I have no idea what this is
.fields = &flds,
.decls = &decls,
.is_tuple = false,
};
}
(the compiler already suggested that I use the reference operator to coerce these) gives the error
/usr/lib/zig/std/fmt.zig:640:22: error: values of type '[]const builtin.Type.StructField' must be comptime-known, but index value is runtime-known
for (value, 0..) |elem, i| {
^~~~~
/usr/lib/zig/std/builtin.zig:346:15: note: struct requires comptime because of this field
type: type,
^~~~
/usr/lib/zig/std/builtin.zig:346:15: note: types are not available at runtime
type: type,
^~~~
/usr/lib/zig/std/builtin.zig:349:20: note: struct requires comptime because of this field
alignment: comptime_int,
^~~~~~~~~~~~
referenced by:
formatType__anon_8517: /usr/lib/zig/std/fmt.zig:608:31
format__anon_4842: /usr/lib/zig/std/fmt.zig:185:23
remaining reference traces hidden; use '-freference-trace' to see all reference traces