Tagged Union test Active Field

Hi,

i’m playing around with tagged unions. I wanted to write a test, to see if some functions I wrote correctly selected the active field of a tagged union. The value that was stored in the union does not matter, so I only wanted to check the Tag.
Like in the code below I used std.testing.expectEqual(.i, tu) and found that it does not compile.
I tried try std.testing.expectEqual(@intFromEnum(Tag.i), @intFromEnum(tu)) as a workaround, by casting everything to their backing integers, which works (in zig 0.16.0).
Is there a reason why I cannot use expectEqual directly?
I assumed, that a tagged union was not directly comparable to anything, but In preparation for this post I played a bit more and found, that if I use equal(.i == tu) it works.
So what is the reasoning behind expectEqual not working? I looked at the source in stdlib and found that expectEqual calls expectEqualInner, which I guess compares also the payloads(?). So is the problem, that tu actually is an instance of the union with an active and set field, and .i is just an enum literal?

Thank you for your explanation.

const Tag = enum { i, f, b };
const TaggedUnion = union(Tag) { i: i32, f: f32, b: bool };

test "uniontest" {
    const tu = TaggedUnion{ .i = 137 };

    // This Works
    try std.testing.expect(@intFromEnum(Tag.i) == @intFromEnum(tu));
    try std.testing.expect(@intFromEnum(Tag.f) != @intFromEnum(tu));
    try std.testing.expect(.i == tu);
    try std.testing.expectEqual(@intFromEnum(Tag.i), @intFromEnum(tu));
    // This does not
    try std.testing.expectEqual(.i, tu);
}

its because expectEqual does @TypeOf(a, b) to resolve a common type, but this does not have the same behaviour as a == b

1 Like

What I would do, because it is more explicit is:

    try std.testing.expectEqual(.i, std.meta.activeTag(tu));
2 Likes

That is exactly the functionality I was looking for. I just could not find it.
Thank you.