aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-04-12 11:36:26 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-04-12 11:36:26 -0700
commit99657dca1fac04e5015203699e3eb0d656d66b09 (patch)
treef7265547fc92b7797a6d695ab271f2e92d43f4fd
parentb0edd8752a00ea191decf302d9802b853d85fd4c (diff)
downloadzig-99657dca1fac04e5015203699e3eb0d656d66b09.tar.gz
zig-99657dca1fac04e5015203699e3eb0d656d66b09.zip
Sema: fix comptime equality of extern unions with same tag
-rw-r--r--src/value.zig13
-rw-r--r--test/behavior/union.zig15
2 files changed, 23 insertions, 5 deletions
diff --git a/src/value.zig b/src/value.zig
index c7960741f6..beb8bc7620 100644
--- a/src/value.zig
+++ b/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) {
diff --git a/test/behavior/union.zig b/test/behavior/union.zig
index 87efcbd5f1..8315ea8a22 100644
--- a/test/behavior/union.zig
+++ b/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));
+}