Switching on pointers to tagged unions

Is there a reason for something like this to not be allowed?

const Value = union(enum) {
    int: i32,
    float: f32,
};

const v: Value = .{ .int = 10 };
const v_ptr = &v;
switch (v_ptr) {
    .int => |i| std.debug.print("int {d}", .{i}),
    .float => |f| std.debug.print("float: {d:.3}", .{f}),
    else => unreachable,
}

1 Like

Because switch (v_ptr.*) { ... } achieves the same thing? :person_shrugging:

7 Likes

Because switches act on the direct values, if given a pointer you will be comparing the address (yes, you can do this), not the dereferenced value.

1 Like

ty! switching on direct addresses seems kinda cursed lol but still cool

It’s more type safe to allow it than forcing to convert to an integer and switching on that, you’d lose the child type and constness doing that.

Unfortunately switching on pointers has been broken for quite a while on the LLVM backend (and I think also on some other backends):

and in light of #23509 it’s probably going to be removed anyway.

6 Likes

Additionally, LLVM 22 has started rejecting the bitcode we produce for switching on pointers. We could try to fix that (in addition to the ways in which it’s already broken), but it’s far more likely we’ll just go ahead and axe the feature with the LLVM 22 upgrade.

6 Likes