mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
compiler: allow equality comparisons for packed unions
This was already possible in practice by just wrapping a packed union into a packed struct. Now it's also possible without doing that.
This commit is contained in:
@@ -2513,6 +2513,13 @@ or
|
||||
<p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
|
||||
to be in a {#link|packed struct#}.</p>
|
||||
<p>All fields in a packed union must have the same {#link|@bitSizeOf#}.</p>
|
||||
|
||||
<p>
|
||||
Equating packed unions results in a comparison of the backing integer,
|
||||
and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}.
|
||||
</p>
|
||||
{#code|test_packed_union_equality.zig#}
|
||||
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Anonymous Union Literals#}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
const std = @import("std");
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
test "packed union equality" {
|
||||
const U = packed union {
|
||||
a: u4,
|
||||
b: i4,
|
||||
};
|
||||
const x: U = .{ .a = 3 };
|
||||
const y: U = .{ .b = 3 };
|
||||
try expectEqual(x, y);
|
||||
}
|
||||
|
||||
// test
|
||||
+1
-2
@@ -334,11 +334,10 @@ pub fn isSelfComparable(ty: Type, zcu: *const Zcu, is_equality_cmp: bool) bool {
|
||||
.undefined,
|
||||
.null,
|
||||
.error_union,
|
||||
.@"union",
|
||||
.frame,
|
||||
=> false,
|
||||
|
||||
.@"struct" => is_equality_cmp and ty.containerLayout(zcu) == .@"packed",
|
||||
.@"struct", .@"union" => is_equality_cmp and ty.containerLayout(zcu) == .@"packed",
|
||||
.pointer => !ty.isSlice(zcu) and (is_equality_cmp or ty.isCPtr(zcu)),
|
||||
.optional => {
|
||||
if (!is_equality_cmp) return false;
|
||||
|
||||
@@ -5750,7 +5750,7 @@ pub const FuncGen = struct {
|
||||
return phi.toValue();
|
||||
},
|
||||
.float => return self.buildFloatCmp(fast, op, operand_ty, .{ lhs, rhs }),
|
||||
.@"struct" => scalar_ty.bitpackBackingInt(zcu),
|
||||
.@"struct", .@"union" => scalar_ty.bitpackBackingInt(zcu),
|
||||
else => unreachable,
|
||||
};
|
||||
const is_signed = int_ty.isSignedInt(zcu);
|
||||
|
||||
@@ -199,3 +199,23 @@ test "packed union with explicit backing integer" {
|
||||
try U.check(.{ .raw = -2 });
|
||||
try comptime U.check(.{ .raw = -2 });
|
||||
}
|
||||
|
||||
test "packed union equality" {
|
||||
const Foo = packed union {
|
||||
a: u4,
|
||||
b: i4,
|
||||
};
|
||||
|
||||
const S = struct {
|
||||
fn doTest(x: Foo, y: Foo) !void {
|
||||
try expect(x == y);
|
||||
try expect(!(x != y));
|
||||
}
|
||||
};
|
||||
|
||||
const x: Foo = .{ .a = 3 };
|
||||
const y: Foo = .{ .b = 3 };
|
||||
|
||||
try S.doTest(x, y);
|
||||
comptime try S.doTest(x, y);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user