Alright, I’m starting to see the issue here, because you can’t do anything like this:
const hmm = struct {
a: u64,
pub const doNotEngage = @compileError("can't use it!");
pub fn bazBux(a: u64) void {
_ = a;
}
};
test "can't touch this" {
const info = @typeInfo(hmm);
inline for (info.Struct.decls) |d| {
const decl_info = @typeInfo(@field(hmm, d.name));
std.debug.print("name: {s}\n", .{d.name});
std.debug.print("type tag {s}\n", .{@tagName(decl_info)});
}
}
That’s worth fixing. I had assumed, incorrectly, that the type of a Declaration would be accessible from the type object, but there appears to be no current way to introspect your way to a field type from the container type, you have to go through a reference to the object.
The fix would be pretty straightforward: add a builtin @fieldType(val, str);
which retrieves the type from the field name. Unlike @TypeOf(@field(val, str))
, this wouldn’t create a field access, and would provide the type of the Forbidden Decl, which is presumably of type NoReturn
.
Alternately / concurrently, add the type of a Declaration to that Declaration. A StructField has the type, so you can do this:
const hmm2 = struct {
a: u64,
b: f64,
};
test "introspect field" {
const info = @typeInfo(hmm2);
inline for (info.Struct.fields) |f| {
const field_info = @typeInfo(f.type);
std.debug.print("name: {s}\n", .{f.name});
std.debug.print("type tag {s}\n", .{@tagName(field_info)});
}
}
Having written code which introspects on the type of a StructField, I didn’t actually realize that wasn’t possible for Declarations, so I didn’t get what the problem is. But they’re just names. That seems like an oversight which should be remedied.
Not to pick on you @chung-leong, because you raised an important issue, but the example you gave to illustrate it was in fact something which shouldn’t work. I agree that this is a problem, unless I missed some trick for introspecting a decl’s type.