Switch to enum literals for list.Head

Unfortunately FieldEnum is causing dependency loops in practice as
introspecting T with @typeInfo() requires T to be fully resolved.

Using an enum literal is far simpler and still avoids the memoization
problems of using slices.
This commit is contained in:
Isaac Freund
2023-02-27 17:27:37 +01:00
parent 676ba262dd
commit dd9ffa05cc

View File

@@ -424,37 +424,10 @@ pub const list = struct {
reverse,
};
/// Compared to std.meta.FieldEnum this version returns an empty enum for opaque types
/// and only supports structs and opaque types.
pub fn FieldEnum(comptime T: type) type {
const field_infos = switch (@typeInfo(T)) {
.Struct => |info| info.fields,
.Opaque => [_]void{},
else => unreachable,
};
var enum_fields: [field_infos.len]std.builtin.Type.EnumField = undefined;
for (field_infos) |field, i| {
enum_fields[i] = .{
.name = field.name,
.value = i,
};
}
return @Type(.{
.Enum = .{
.layout = .Auto,
.tag_type = std.math.IntFittingRange(0, field_infos.len -| 1),
.fields = &enum_fields,
.decls = &.{},
.is_exhaustive = true,
},
});
}
/// This has the same ABI as wl.list.Link/wl_list. If link_field is null, then
/// T.getLink()/T.fromLink() will be used. This allows for compatiability
/// with wl.Client and wl.Resource
pub fn Head(comptime T: type, comptime link_field: ?FieldEnum(T)) type {
pub fn Head(comptime T: type, comptime link_field: ?@Type(.EnumLiteral)) type {
return extern struct {
const Self = @This();