Commit 99657dca1f

Andrew Kelley <andrew@ziglang.org>
2022-04-12 20:36:26
Sema: fix comptime equality of extern unions with same tag
1 parent b0edd87
Changed files (2)
src
test
behavior
src/value.zig
@@ -2122,19 +2122,22 @@ pub const Value = extern union {
                 const b_union = b.castTag(.@"union").?.data;
                 switch (ty.containerLayout()) {
                     .Packed, .Extern => {
-                        // In this case, we must disregard mismatching tags and compare
-                        // based on the in-memory bytes of the payloads.
-                        @panic("TODO implement comparison of extern union values");
+                        const tag_ty = ty.unionTagTypeHypothetical();
+                        if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
+                            // In this case, we must disregard mismatching tags and compare
+                            // based on the in-memory bytes of the payloads.
+                            @panic("TODO comptime comparison of extern union values with mismatching tags");
+                        }
                     },
                     .Auto => {
                         const tag_ty = ty.unionTagTypeHypothetical();
                         if (!a_union.tag.eql(b_union.tag, tag_ty, target)) {
                             return false;
                         }
-                        const active_field_ty = ty.unionFieldType(a_union.tag, target);
-                        return a_union.val.eql(b_union.val, active_field_ty, target);
                     },
                 }
+                const active_field_ty = ty.unionFieldType(a_union.tag, target);
+                return a_union.val.eql(b_union.val, active_field_ty, target);
             },
             else => {},
         } else if (a_tag == .null_value or b_tag == .null_value) {
test/behavior/union.zig
@@ -1168,3 +1168,18 @@ test "union with a large struct field" {
     var s: S = undefined;
     U.foo(U{ .s = s });
 }
+
+test "comptime equality of extern unions with same tag" {
+    const S = struct {
+        const U = extern union {
+            a: i32,
+            b: f32,
+        };
+        fn foo(comptime x: U) i32 {
+            return x.a;
+        }
+    };
+    const a = S.U{ .a = 1234 };
+    const b = S.U{ .a = 1234 };
+    try expect(S.foo(a) == S.foo(b));
+}