Commit 0ffeec4b4d

rohlem <rohlemF@gmail.com>
2024-06-18 19:04:16
fix std.meta.eql for comptime-only union
switch from `inline for` with `std.mem.eql` to `inline else` and tag comparison. add previously-failing test code.
1 parent 17ce3e5
Changed files (1)
lib
lib/std/meta.zig
@@ -757,16 +757,13 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool {
         },
         .Union => |info| {
             if (info.tag_type) |UnionTag| {
-                const tag_a = activeTag(a);
-                const tag_b = activeTag(b);
+                const tag_a: UnionTag = a;
+                const tag_b: UnionTag = b;
                 if (tag_a != tag_b) return false;
 
-                inline for (info.fields) |field_info| {
-                    if (@field(UnionTag, field_info.name) == tag_a) {
-                        return eql(@field(a, field_info.name), @field(b, field_info.name));
-                    }
-                }
-                return false;
+                return switch (a) {
+                    inline else => |val, tag| return eql(val, @field(b, @tagName(tag))),
+                };
             }
 
             @compileError("cannot compare untagged union type " ++ @typeName(T));
@@ -858,6 +855,15 @@ test eql {
 
     try testing.expect(eql(v1, v2));
     try testing.expect(!eql(v1, v3));
+
+    const CU = union(enum) {
+        a: void,
+        b: void,
+        c: comptime_int,
+    };
+
+    try testing.expect(eql(CU{ .a = {} }, .a));
+    try testing.expect(!eql(CU{ .a = {} }, .b));
 }
 
 test intToEnum {