Description
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?