zig icon indicating copy to clipboard operation
zig copied to clipboard

Crash iterating over tuple elements via pointer in comptime

Open michaelbartnett opened this issue 1 year ago • 0 comments

Zig Version

0.12.0-dev.3434+e90583f5d

Steps to Reproduce and Observed Behavior

This code produces a compiler crash on master:

const std = @import("std");

pub const attributes = struct {
    pub fn first(comptime T: type, comptime AttribType: type) ?*const AttribType {
        inline for (&T.ATTRIBUTES) |*attrib| {
            if (comptime @TypeOf(attrib.*) == AttribType) {
                return attrib;
            }
        }
        return null;
    }
};

pub const SimpleAttribute = struct {
    n: i32,
};

pub const SomeTypeWithAttributes = struct {
    m: u8 = 255,

    pub const ATTRIBUTES = .{
        SimpleAttribute{ .n = 42 },
    };
};

pub fn main() void {
    var value: i32 = -1;
    if (attributes.first(SomeTypeWithAttributes, SimpleAttribute)) |pattr| {
        value = pattr.n;
    }

    std.log.info("SimpleAttribute.n of SomeTypeWithAttributes resolved to {}", .{value});
}

Expected Behavior

Expected no crash ofc :)

I also expect it to return the address of the element of the tuple declared in SomeTypeWithAttributes.

Squirl (🙌) on the discord pointed out that changing this function to return values instead of addresses gets rid of the crash, and that if I wanted to avoid making a bunch of copies I could still take the address of the comptime result value and it would likely dedupe.

This totally works for my current use case, although this leaves it in a less-semantically-clear state from the user's perspective. If I take the address of the result of the comptime function call result, is it the address of SomeTypeWithAttributes.ATTRIBUTES[0] or is it the address of a copy of that static data at a different location in memory at runtime? If that's not information that Zig wants to expose to the programmer, then maybe worth a compiler message or a note in docs?

michaelbartnett avatar Mar 24 '24 23:03 michaelbartnett