| 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,8 +7079,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { |
| 7079 | if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) { | 7079 | if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) { |
| 7080 | TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag); | 7080 | TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag); |
| 7081 | assert(field != nullptr); | 7081 | assert(field != nullptr); |
| 7082 | if (!type_has_bits(g, field->type_entry)) | ||
| 7083 | return true; | ||
| 7084 | assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr); | 7082 | assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr); |
| 7085 | return const_values_equal(g, union1->payload, union2->payload); | 7083 | return const_values_equal(g, union1->payload, union2->payload); |
| 7086 | } | 7084 | } |
test/stage1/behavior.zig+1| ... | @@ -56,6 +56,7 @@ comptime { | ... | @@ -56,6 +56,7 @@ comptime { |
| 56 | _ = @import("behavior/bugs/6456.zig"); | 56 | _ = @import("behavior/bugs/6456.zig"); |
| 57 | _ = @import("behavior/bugs/6781.zig"); | 57 | _ = @import("behavior/bugs/6781.zig"); |
| 58 | _ = @import("behavior/bugs/6850.zig"); | 58 | _ = @import("behavior/bugs/6850.zig"); |
| 59 | _ = @import("behavior/bugs/7047.zig"); | ||
| 59 | _ = @import("behavior/bugs/394.zig"); | 60 | _ = @import("behavior/bugs/394.zig"); |
| 60 | _ = @import("behavior/bugs/421.zig"); | 61 | _ = @import("behavior/bugs/421.zig"); |
| 61 | _ = @import("behavior/bugs/529.zig"); | 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 | } | ||