Sema: fix comptime equality of extern unions with same tag

This commit is contained in:
Andrew Kelley 2022-04-12 11:36:26 -07:00
parent b0edd8752a
commit 99657dca1f
2 changed files with 23 additions and 5 deletions

View File

@ -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) {

View File

@ -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));
}