| author | |
| committer | |
| log | 85665386c68d176c839048b55f5249d923087890 |
| tree | ee1f14e340635f6ee6603f9c3a32a000f238288b |
| parent | 2c0caa853359f46be0b72d32def8287c50a3507f |
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 #70473 files changed, 23 insertions(+), 2 deletions(-)
src/stage1/analyze.cpp-2| ... | ... | @@ -7079,8 +7079,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { |
| 7079 | 7079 | if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) { |
| 7080 | 7080 | TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag); |
| 7081 | 7081 | assert(field != nullptr); |
| 7082 | if (!type_has_bits(g, field->type_entry)) | |
| 7083 | return true; | |
| 7084 | 7082 | assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr); |
| 7085 | 7083 | return const_values_equal(g, union1->payload, union2->payload); |
| 7086 | 7084 | } |
test/stage1/behavior.zig+1| ... | ... | @@ -56,6 +56,7 @@ comptime { |
| 56 | 56 | _ = @import("behavior/bugs/6456.zig"); |
| 57 | 57 | _ = @import("behavior/bugs/6781.zig"); |
| 58 | 58 | _ = @import("behavior/bugs/6850.zig"); |
| 59 | _ = @import("behavior/bugs/7047.zig"); | |
| 59 | 60 | _ = @import("behavior/bugs/394.zig"); |
| 60 | 61 | _ = @import("behavior/bugs/421.zig"); |
| 61 | 62 | _ = @import("behavior/bugs/529.zig"); |
test/stage1/behavior/bugs/7047.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const U = union(enum) { | |
| 4 | T: type, | |
| 5 | N: void, | |
| 6 | }; | |
| 7 | ||
| 8 | fn S(comptime query: U) type { | |
| 9 | return struct { | |
| 10 | fn tag() type { | |
| 11 | return query.T; | |
| 12 | } | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | test "compiler doesn't consider equal unions with different 'type' payload" { | |
| 17 | const s1 = S(U{ .T = u32 }).tag(); | |
| 18 | std.testing.expectEqual(u32, s1); | |
| 19 | ||
| 20 | const s2 = S(U{ .T = u64 }).tag(); | |
| 21 | std.testing.expectEqual(u64, s2); | |
| 22 | } |