Comptime array access

Hi, I struggle with comptime created array indexing when the array contains structures with a field of type type.

The following code has no functional purpose, only to show my question:

const Data = struct {
    type: type,
    value: i64,
};

fn genData(T: type, value: i64) Data {
    return .{ .type = T, .value = value };
}

fn create(index: usize) void {
    const d = datas[index]; // <-- Error here
    // ...
}

const datas = [_]Data{ genData(f64, 5), genData(usize, 8) };

pub fn main() !void {}

The error is:

question.zig:16:21: error: values of type '[2]question.Data' must be comptime-known, but index value is runtime-known
    const d = datas[index];
                    ^~~~~
question.zig:4:11: note: struct requires comptime because of this field
    type: type,
          ^~~~
question.zig:4:11: note: types are not available at runtime

If I remove the field type: type from the structure there is no error anymore.

The only way I found is to implement create like this:

fn create(index: usize) void {
    inline for (datas, 0..) |d, i| {
        if (index == i) {
            // ...
        }
    }
}

Is there a way to index a comptime created array of structures containing comptime fields?
Thanks!

Change

fn create(index: usize) void {

to

fn create(comptime index: usize) void {

Yes I should have mentioned that the index isn’t comptime know, I would like to use the array at runtime which is possible as long as there is no comptime field in the structures (like type: type field)

Is following what you are trying to achieve?

You call create at runtime. create accesses an element from an array with an runtime known index. This array does contain comptime-only fields (like type), but create only accesses fields, which are accessible at runtime (like value).

I’d like to access both fields (type and value) at runtime

How do you want to use type at runtime?

The idea was to be able to do something like:

const obj = try gpa.create(T);

With T coming from the Data type field and to get the correct data I compute at runtime an index to access datas array (I don’t know if it’s clear)

I’m not sure if what you are trying to do is the correct way to solve your issue (XY problem), but if you want to execute different code, depending on a runtime variable, where the only difference between the code variants is this runtime variable as a comptime value you can do:

fn create(index: usize) void {
    switch (index) {
        inline 0...datas.len - 1 => |i| {
            // this block is compiled with every possible value of i from 0 to datas.len - 1 (both inclusive)

            const d = datas[i];
            // ...
            _ = d;
        },
        else => unreachable,
    }
}

See Inline Switch Prongs of the zig docs.

3 Likes

Actually realy smart! Gonna try this tomorrow thanks for your time :slight_smile: