How to use StructField.default_value

I’m making a function to generate a default value of any struct type at comptime, it should use the struct’s default values if present, but set any bool fields to false and optional fields to null. Here’s my code:

 fn makeConfig(comptime Config: type) Config {
    var config: Config = undefined;
    if (@typeInfo(Config) != .Struct) @compileError("Config must be a struct type.");

    inline for (@typeInfo(Config).Struct.fields) |field| {
        if (field.default_value) |default| {
            // Problem line:
            @field(config, field.name) = @as(field.type, default.*);
            continue;
        }

        switch (@typeInfo(field.type)) {
            .Bool => @field(config, field.name) = false,
            .Optional => @field(config, field.name) = null,
            else => @compileError("cannot generate default"),
        }
    }

    return config;
}

The problem is that on the line where it sets the value to the existing default, I get a compile error: cannot load opaque type 'anyopaque'. I understand that the default value is type erased, but can I not cast it to the type of the field? Using @as(field.type, default.*) does not work either.

Since it’s a pointer to an anyopaque I think you need a pointer cast?

@as(*const field.type, @ptrCast(default)).*
6 Likes

Ok, this almost works but I also need to @alignCast:

@field(config, field.name) = @as(*const field.type, @alignCast(@ptrCast(default))).*;

Thanks :).

4 Likes

Just in case. It seems to me you are trying to reimplement std.mem.zeroInit.

5 Likes

I was not aware, thanks for sharing!