Sema: implement union value equality at comptime

Still TODO is extern unions.
This commit is contained in:
Andrew Kelley 2022-02-26 18:01:12 -07:00
parent e999a925fa
commit 32e89a98d8
3 changed files with 27 additions and 2 deletions

View File

@ -2934,6 +2934,14 @@ pub const Type = extern union {
}; };
} }
/// Asserts the type is a union; returns the tag type, even if the tag will
/// not be stored at runtime.
pub fn unionTagTypeHypothetical(ty: Type) Type {
const union_obj = ty.cast(Payload.Union).?.data;
assert(union_obj.haveFieldTypes());
return union_obj.tag_ty;
}
pub fn unionFields(ty: Type) Module.Union.Fields { pub fn unionFields(ty: Type) Module.Union.Fields {
const union_obj = ty.cast(Payload.Union).?.data; const union_obj = ty.cast(Payload.Union).?.data;
assert(union_obj.haveFieldTypes()); assert(union_obj.haveFieldTypes());

View File

@ -1902,6 +1902,25 @@ pub const Value = extern union {
} }
return true; return true;
}, },
.@"union" => {
const a_union = a.castTag(.@"union").?.data;
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");
},
.Auto => {
const tag_ty = ty.unionTagTypeHypothetical();
if (!a_union.tag.eql(b_union.tag, tag_ty)) {
return false;
}
const active_field_ty = ty.unionFieldType(a_union.tag);
return a_union.val.eql(b_union.val, active_field_ty);
},
}
},
else => {}, else => {},
} else if (a_tag == .null_value or b_tag == .null_value) { } else if (a_tag == .null_value or b_tag == .null_value) {
return false; return false;

View File

@ -723,8 +723,6 @@ test "@enumToInt works on unions" {
} }
test "comptime union field value equality" { test "comptime union field value equality" {
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
const a0 = Setter(Attribute{ .A = false }); const a0 = Setter(Attribute{ .A = false });
const a1 = Setter(Attribute{ .A = true }); const a1 = Setter(Attribute{ .A = true });
const a2 = Setter(Attribute{ .A = false }); const a2 = Setter(Attribute{ .A = false });