Commit 611d4bc6a1

Michael Dusan <michael.dusan@gmail.com>
2019-04-15 04:47:53
stage1: const_values_equal support tagged union
1 parent 52caf31
Changed files (2)
src
test
stage1
behavior
src/analyze.cpp
@@ -5158,11 +5158,10 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
             if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
                 TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
                 assert(field != nullptr);
-                if (type_has_bits(field->type_entry)) {
-                    zig_panic("TODO const expr analyze union field value for equality");
-                } else {
+                if (!type_has_bits(field->type_entry))
                     return true;
-                }
+                assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
+                return const_values_equal(g, union1->payload, union2->payload);
             }
             return false;
         }
test/stage1/behavior/union.zig
@@ -365,3 +365,40 @@ test "@enumToInt works on unions" {
     expect(@enumToInt(b) == 1);
     expect(@enumToInt(c) == 2);
 }
+
+const Attribute = union(enum) {
+    A: bool,
+    B: u8,
+};
+
+fn setAttribute(attr: Attribute) void {}
+
+fn Setter(attr: Attribute) type {
+    return struct{
+        fn set() void {
+            setAttribute(attr);
+        }
+    };
+}
+
+test "comptime union field value equality" {
+    const a0 = Setter(Attribute{ .A = false });
+    const a1 = Setter(Attribute{ .A = true });
+    const a2 = Setter(Attribute{ .A = false });
+
+    const b0 = Setter(Attribute{ .B = 5 });
+    const b1 = Setter(Attribute{ .B = 9 });
+    const b2 = Setter(Attribute{ .B = 5 });
+
+    expect(a0 == a0);
+    expect(a1 == a1);
+    expect(a0 == a2);
+
+    expect(b0 == b0);
+    expect(b1 == b1);
+    expect(b0 == b2);
+
+    expect(a0 != b0);
+    expect(a0 != a1);
+    expect(b0 != b1);
+}