Skip to content

Deserialization of comptime structs #21

@gballet

Description

@gballet

This is a tracking issue for the following problem:

The implementation of structure deserialization uses a reference to @field, which is a runtime expression.

If a structure is declared const in a test, it will be comptime and this causes a problem where a reference to a comptime object is taken at runtime, which is not possible.

Reproduction of the problem:

const std = @import("std");
const builtin = @import("builtin");

pub fn main() !void {
    const mystruc = .{ .age = @as(u8, 5), .name = @as([]const u8, "roger") };
    const tinfo = @typeInfo(@TypeOf(mystruc));
    inline for (tinfo.Struct.fields) |field| {
    	const x = &@field(mystruc, field.name);
        std.debug.print("field = {any}\n", .{x});
    }
}

output:

prog.zig:11:45: error: runtime value contains reference to comptime var
/tmp/tmpdir_tg2Kt7nRRXakarUS/tmp_kfQvMGZT1vr00sIzprog.zig:11:45: note: comptime var pointers are not available at runtime

Update

Note that dereferencing the pointer works:

const std = @import("std");
const builtin = @import("builtin");

pub fn main() !void {
    const mystruc = .{ .age = @as(u8, 5), .name = @as([]const u8, "roger") };
    const tinfo = @typeInfo(@TypeOf(mystruc));
    inline for (tinfo.Struct.fields) |field| {
    	const x = &@field(mystruc, field.name);
        std.debug.print("field = {any}\n", .{x.*});
    }
}

output:

field = 5
field = { 114, 111, 103, 101, 114 }

which is normal, since there no longer is a reference during the comptime evaluation. So the workaround would be to somehow not pass a pointer in that case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions