zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 4d4ab1e69a40fb11d19e93b42a02016f9d009aef (tree)
parent 06a3a69e6f38798b1768976520b8db40c9a210bf
Author: LemonBoy <thatlemon@gmail.com>
Date:   Tue, 10 Nov 2020 17:55:16 +0100

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

Diffstat:
Msrc/stage1/analyze.cpp | 2--
Mtest/stage1/behavior.zig | 1+
Atest/stage1/behavior/bugs/7047.zig | 22++++++++++++++++++++++
3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/stage1/analyze.cpp b/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); } diff --git a/test/stage1/behavior.zig b/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"); diff --git a/test/stage1/behavior/bugs/7047.zig b/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); +}