authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 18:01:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 20:59:23-07:00
log32e89a98d82c0f4505a3f3d4cd72e7db2eadfbb9
treead3f28c440c3ff6e1ad5cfd5bb05a867331e4b0e
parente999a925fade363886538722df7605b01da220d1

Sema: implement union value equality at comptime

Still TODO is extern unions.

3 files changed, 27 insertions(+), 2 deletions(-)

src/type.zig+8
......@@ -2934,6 +2934,14 @@ pub const Type = extern union {
29342934 };
29352935 }
29362936
2937 /// Asserts the type is a union; returns the tag type, even if the tag will
2938 /// not be stored at runtime.
2939 pub fn unionTagTypeHypothetical(ty: Type) Type {
2940 const union_obj = ty.cast(Payload.Union).?.data;
2941 assert(union_obj.haveFieldTypes());
2942 return union_obj.tag_ty;
2943 }
2944
29372945 pub fn unionFields(ty: Type) Module.Union.Fields {
29382946 const union_obj = ty.cast(Payload.Union).?.data;
29392947 assert(union_obj.haveFieldTypes());
src/value.zig+19
......@@ -1902,6 +1902,25 @@ pub const Value = extern union {
19021902 }
19031903 return true;
19041904 },
1905 .@"union" => {
1906 const a_union = a.castTag(.@"union").?.data;
1907 const b_union = b.castTag(.@"union").?.data;
1908 switch (ty.containerLayout()) {
1909 .Packed, .Extern => {
1910 // In this case, we must disregard mismatching tags and compare
1911 // based on the in-memory bytes of the payloads.
1912 @panic("TODO implement comparison of extern union values");
1913 },
1914 .Auto => {
1915 const tag_ty = ty.unionTagTypeHypothetical();
1916 if (!a_union.tag.eql(b_union.tag, tag_ty)) {
1917 return false;
1918 }
1919 const active_field_ty = ty.unionFieldType(a_union.tag);
1920 return a_union.val.eql(b_union.val, active_field_ty);
1921 },
1922 }
1923 },
19051924 else => {},
19061925 } else if (a_tag == .null_value or b_tag == .null_value) {
19071926 return false;
test/behavior/union.zig-2
......@@ -723,8 +723,6 @@ test "@enumToInt works on unions" {
723723}
724724
725725test "comptime union field value equality" {
726 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
727
728726 const a0 = Setter(Attribute{ .A = false });
729727 const a1 = Setter(Attribute{ .A = true });
730728 const a2 = Setter(Attribute{ .A = false });