I’m starting to think that’s what’s going on here. In godbolt, I can remove the logic of your branches and just see what branches we’re getting into for your minimal example:
const std = @import("std");
fn traverse(comptime val: anytype) void {
const T = @TypeOf(val);
switch (@typeInfo(T)) {
.Union => {
if (@typeInfo(T).Union.tag_type) |Tag| {
switch (@as(Tag, val)) {
inline else => |tag| {
traverse(@field(val, @tagName(tag)));
},
}
}
},
.Pointer => {
@compileError("In pointer branch");
},
.Int => {
@compileLog("In integer branch");
},
else => {}
}
}
For the following code, we hit the integer branch only:
pub fn main() !void {
const Union = union(enum) {
int: u8,
self: *const @This(),
};
const val = Union{ .int = 10 };
comptime traverse(val);
}