aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2020-09-14 16:43:49 +0300
committerGitHub <noreply@github.com>2020-09-14 16:43:49 +0300
commitd073836894df8b9fb56f24f577a51dd09a85a932 (patch)
tree920723ea7cbe577934f0fb9670332f40dc7fd94a /lib
parentc49435f76b07cbf3fdd6a10303a1a0ee4290e59a (diff)
parentacdf1f0bde9a07cae2fbe33739f5f4aee7989f7b (diff)
downloadzig-d073836894df8b9fb56f24f577a51dd09a85a932.tar.gz
zig-d073836894df8b9fb56f24f577a51dd09a85a932.zip
Merge pull request #6172 from tadeokondrak/@Type(.Union)
Implement @Type for Union
Diffstat (limited to 'lib')
-rw-r--r--lib/std/builtin.zig1
-rw-r--r--lib/std/fmt.zig2
-rw-r--r--lib/std/hash/auto_hash.zig5
-rw-r--r--lib/std/io/serialization.zig4
-rw-r--r--lib/std/json.zig4
-rw-r--r--lib/std/meta.zig12
6 files changed, 14 insertions, 14 deletions
diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig
index 911a0eb15c..52b8f641cd 100644
--- a/lib/std/builtin.zig
+++ b/lib/std/builtin.zig
@@ -317,7 +317,6 @@ pub const TypeInfo = union(enum) {
/// therefore must be kept in sync with the compiler implementation.
pub const UnionField = struct {
name: []const u8,
- enum_field: ?EnumField,
field_type: type,
};
diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig
index a652bd8c21..8d31733959 100644
--- a/lib/std/fmt.zig
+++ b/lib/std/fmt.zig
@@ -399,7 +399,7 @@ pub fn formatType(
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) {
+ if (value == @field(UnionTagType, u_field.name)) {
try formatType(@field(value, u_field.name), fmt, options, writer, max_depth - 1);
}
}
diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig
index 5877c77b5d..2e707d5450 100644
--- a/lib/std/hash/auto_hash.zig
+++ b/lib/std/hash/auto_hash.zig
@@ -139,9 +139,8 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
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);
+ if (@field(tag_type, field.name) == tag) {
+ hash(hasher, @field(key, field.name), strat);
// TODO use a labelled break when it does not crash the compiler. cf #2908
// break :blk;
return;
diff --git a/lib/std/io/serialization.zig b/lib/std/io/serialization.zig
index 925c929cee..79a12989b8 100644
--- a/lib/std/io/serialization.zig
+++ b/lib/std/io/serialization.zig
@@ -156,7 +156,7 @@ 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) {
+ if (@enumToInt(@field(TagType, field_info.name)) == tag) {
const name = field_info.name;
const FieldType = field_info.field_type;
ptr.* = @unionInit(C, name, undefined);
@@ -320,7 +320,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
// 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)) {
+ if (@field(TagType, field_info.name) == active_tag) {
const name = field_info.name;
const FieldType = field_info.field_type;
try self.serialize(@field(value, name));
diff --git a/lib/std/json.zig b/lib/std/json.zig
index 2f8a70d0ef..cf479ab2cd 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -1613,7 +1613,7 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
.Union => |unionInfo| {
if (unionInfo.tag_type) |UnionTagType| {
inline for (unionInfo.fields) |u_field| {
- if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
+ if (value == @field(UnionTagType, u_field.name)) {
parseFree(u_field.field_type, @field(value, u_field.name), options);
break;
}
@@ -2458,7 +2458,7 @@ pub fn stringify(
const info = @typeInfo(T).Union;
if (info.tag_type) |UnionTagType| {
inline for (info.fields) |u_field| {
- if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
+ if (value == @field(UnionTagType, u_field.name)) {
return try stringify(@field(value, u_field.name), options, out_stream);
}
}
diff --git a/lib/std/meta.zig b/lib/std/meta.zig
index 73e0661498..b27f168ac9 100644
--- a/lib/std/meta.zig
+++ b/lib/std/meta.zig
@@ -465,10 +465,13 @@ 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;
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, @tagName(tag)))
+ return field_info.field_type;
}
+
unreachable;
}
@@ -504,15 +507,14 @@ 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;
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));
+ if (@field(Tag, field_info.name) == tag_a) {
+ return eql(@field(a, field_info.name), @field(b, field_info.name));
}
}
return false;