Commit 85665386c6

LemonBoy <thatlemon@gmail.com>
2020-11-10 17:55:16
stage1: Fix comparison of unions containing zero-sized types
The code tried to be too smart and skipped the equality (returning true) if the payload type was zero-sized. This optimization is completely wrong when the union payload is a metatype! Fixes #7047
1 parent 2c0caa8
Changed files (3)
src
test
stage1
behavior
src/stage1/analyze.cpp
@@ -7079,8 +7079,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *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(g, 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);
             }
test/stage1/behavior/bugs/7047.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+
+const U = union(enum) {
+    T: type,
+    N: void,
+};
+
+fn S(comptime query: U) type {
+    return struct {
+        fn tag() type {
+            return query.T;
+        }
+    };
+}
+
+test "compiler doesn't consider equal unions with different 'type' payload" {
+    const s1 = S(U{ .T = u32 }).tag();
+    std.testing.expectEqual(u32, s1);
+
+    const s2 = S(U{ .T = u64 }).tag();
+    std.testing.expectEqual(u64, s2);
+}
test/stage1/behavior.zig
@@ -56,6 +56,7 @@ comptime {
     _ = @import("behavior/bugs/6456.zig");
     _ = @import("behavior/bugs/6781.zig");
     _ = @import("behavior/bugs/6850.zig");
+    _ = @import("behavior/bugs/7047.zig");
     _ = @import("behavior/bugs/394.zig");
     _ = @import("behavior/bugs/421.zig");
     _ = @import("behavior/bugs/529.zig");