Update standard library for removal of TypeInfo.UnionField.enum_field
parent
ff2ed966bb
commit
ac19ccf595
|
@ -395,11 +395,17 @@ pub fn formatType(
|
|||
}
|
||||
const info = @typeInfo(T).Union;
|
||||
if (info.tag_type) |UnionTagType| {
|
||||
const tag_info = @typeInfo(UnionTagType).Enum;
|
||||
try writer.writeAll("{ .");
|
||||
try writer.writeAll(@tagName(@as(UnionTagType, value)));
|
||||
try writer.writeAll(" = ");
|
||||
inline for (info.fields) |u_field| {
|
||||
if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
|
||||
comptime var tag_value: @TagType(UnionTagType) = undefined;
|
||||
inline for (tag_info.fields) |e_field| {
|
||||
if (comptime mem.eql(u8, u_field.name, e_field.name))
|
||||
tag_value = e_field.value;
|
||||
}
|
||||
if (@enumToInt(@as(UnionTagType, value)) == tag_value) {
|
||||
try formatType(@field(value, u_field.name), fmt, options, writer, max_depth - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,12 +136,17 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
|
|||
|
||||
.Union => |info| {
|
||||
if (info.tag_type) |tag_type| {
|
||||
const tag_info = @typeInfo(tag_type).Enum;
|
||||
const tag = meta.activeTag(key);
|
||||
const s = hash(hasher, tag, strat);
|
||||
inline for (info.fields) |field| {
|
||||
const enum_field = field.enum_field.?;
|
||||
if (enum_field.value == @enumToInt(tag)) {
|
||||
hash(hasher, @field(key, enum_field.name), strat);
|
||||
comptime var tag_value: @TagType(tag_type) = undefined;
|
||||
inline for (tag_info.fields) |enum_field| {
|
||||
if (comptime mem.eql(u8, field.name, enum_field.name))
|
||||
tag_value = enum_field.value;
|
||||
}
|
||||
if (@enumToInt(tag) == tag_value) {
|
||||
hash(hasher, @field(key, field.name), strat);
|
||||
// TODO use a labelled break when it does not crash the compiler. cf #2908
|
||||
// break :blk;
|
||||
return;
|
||||
|
|
|
@ -149,6 +149,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
|
|||
.Union => {
|
||||
const info = @typeInfo(C).Union;
|
||||
if (info.tag_type) |TagType| {
|
||||
const tag_info = @typeInfo(TagType).Enum;
|
||||
//we avoid duplicate iteration over the enum tags
|
||||
// by getting the int directly and casting it without
|
||||
// safety. If it is bad, it will be caught anyway.
|
||||
|
@ -156,7 +157,13 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
|
|||
const tag = try self.deserializeInt(TagInt);
|
||||
|
||||
inline for (info.fields) |field_info| {
|
||||
if (field_info.enum_field.?.value == tag) {
|
||||
comptime var tag_value: TagInt = undefined;
|
||||
inline for (tag_info.fields) |enum_field_info| {
|
||||
if (comptime std.mem.eql(u8, field_info.name, enum_field_info.name)) {
|
||||
tag_value = enum_field_info.value;
|
||||
}
|
||||
}
|
||||
if (tag_value == tag) {
|
||||
const name = field_info.name;
|
||||
const FieldType = field_info.field_type;
|
||||
ptr.* = @unionInit(C, name, undefined);
|
||||
|
@ -314,13 +321,20 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
|
|||
.Union => {
|
||||
const info = @typeInfo(T).Union;
|
||||
if (info.tag_type) |TagType| {
|
||||
const tag_info = @typeInfo(TagType).Enum;
|
||||
const active_tag = meta.activeTag(value);
|
||||
try self.serialize(active_tag);
|
||||
//This inline loop is necessary because active_tag is a runtime
|
||||
// value, but @field requires a comptime value. Our alternative
|
||||
// is to check each field for a match
|
||||
inline for (info.fields) |field_info| {
|
||||
if (field_info.enum_field.?.value == @enumToInt(active_tag)) {
|
||||
comptime var tag_value: @TagType(TagType) = undefined;
|
||||
inline for (tag_info.fields) |enum_field_info| {
|
||||
if (comptime std.mem.eql(u8, field_info.name, enum_field_info.name)) {
|
||||
tag_value = enum_field_info.value;
|
||||
}
|
||||
}
|
||||
if (tag_value == @enumToInt(active_tag)) {
|
||||
const name = field_info.name;
|
||||
const FieldType = field_info.field_type;
|
||||
try self.serialize(@field(value, name));
|
||||
|
|
|
@ -1612,8 +1612,14 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
|
|||
},
|
||||
.Union => |unionInfo| {
|
||||
if (unionInfo.tag_type) |UnionTagType| {
|
||||
const tag_info = @typeInfo(UnionTagType).Enum;
|
||||
inline for (unionInfo.fields) |u_field| {
|
||||
if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
|
||||
comptime var tag_value: @TagType(UnionTagType) = undefined;
|
||||
inline for (tag_info.fields) |e_field| {
|
||||
if (comptime mem.eql(u8, u_field.name, e_field.name))
|
||||
tag_value = e_field.value;
|
||||
}
|
||||
if (@enumToInt(@as(UnionTagType, value)) == tag_value) {
|
||||
parseFree(u_field.field_type, @field(value, u_field.name), options);
|
||||
break;
|
||||
}
|
||||
|
@ -2457,8 +2463,14 @@ pub fn stringify(
|
|||
|
||||
const info = @typeInfo(T).Union;
|
||||
if (info.tag_type) |UnionTagType| {
|
||||
const tag_info = @typeInfo(UnionTagType).Enum;
|
||||
inline for (info.fields) |u_field| {
|
||||
if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
|
||||
comptime var tag_value: @TagType(UnionTagType) = undefined;
|
||||
inline for (tag_info.fields) |e_field| {
|
||||
if (comptime mem.eql(u8, u_field.name, e_field.name))
|
||||
tag_value = e_field.value;
|
||||
}
|
||||
if (@enumToInt(@as(UnionTagType, value)) == tag_value) {
|
||||
return try stringify(@field(value, u_field.name), options, out_stream);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -465,10 +465,19 @@ pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type {
|
|||
testing.expect(trait.is(.Union)(U));
|
||||
|
||||
const info = @typeInfo(U).Union;
|
||||
const tag_info = @typeInfo(@TagType(U)).Enum;
|
||||
|
||||
comptime var name: []const u8 = undefined;
|
||||
inline for (tag_info.fields) |enum_field_info| {
|
||||
if (@enumToInt(tag) == enum_field_info.value)
|
||||
name = enum_field_info.name;
|
||||
}
|
||||
|
||||
inline for (info.fields) |field_info| {
|
||||
if (field_info.enum_field.?.value == @enumToInt(tag)) return field_info.field_type;
|
||||
if (comptime mem.eql(u8, field_info.name, name))
|
||||
return field_info.field_type;
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
|
@ -504,15 +513,20 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool {
|
|||
}
|
||||
},
|
||||
.Union => |info| {
|
||||
if (info.tag_type) |_| {
|
||||
if (info.tag_type) |Tag| {
|
||||
const tag_a = activeTag(a);
|
||||
const tag_b = activeTag(b);
|
||||
if (tag_a != tag_b) return false;
|
||||
|
||||
const tag_info = @typeInfo(Tag).Enum;
|
||||
inline for (info.fields) |field_info| {
|
||||
const enum_field = field_info.enum_field.?;
|
||||
if (enum_field.value == @enumToInt(tag_a)) {
|
||||
return eql(@field(a, enum_field.name), @field(b, enum_field.name));
|
||||
comptime var tag_value: @TagType(Tag) = undefined;
|
||||
inline for (tag_info.fields) |enum_field_info| {
|
||||
if (comptime mem.eql(u8, field_info.name, enum_field_info.name))
|
||||
tag_value = enum_field_info.value;
|
||||
}
|
||||
if (tag_value == @enumToInt(tag_a)) {
|
||||
return eql(@field(a, field_info.name), @field(b, field_info.name));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue