Skip to content

when multiple union fields share a body in a switch prong, use a peer result type cast, rather than requiring identical types #2812

Closed
@andrewrk

Description

@andrewrk

Followup from #1107.

This test passes now:

test "switch prongs with cases with identical payload types" {
    const Union = union(enum) {
        A: usize,
        B: isize,
        C: usize,
    };
    const S = struct {
        fn doTheTest() void {
            doTheSwitch1(Union{ .A = 8 });
            doTheSwitch2(Union{ .B = -8 });
        }
        fn doTheSwitch1(u: Union) void {
            switch (u) {
                .A, .C => |e| {
                    expect(@typeOf(e) == usize);
                    expect(e == 8);
                },
                .B => |e| @panic("fail"),
            }
        }
        fn doTheSwitch2(u: Union) void {
            switch (u) {
                .A, .C => |e| @panic("fail"),
                .B => |e| {
                    expect(@typeOf(e) == isize);
                    expect(e == -8);
                },
            }
        }
    };
    S.doTheTest();
    comptime S.doTheTest();
}

But this diff:

-        A: usize,
+        A: u8,
        B: isize,
-        C: usize,
+        C: u16,

Gives this error:

/home/andy/downloads/zig/build/test.zig:18:28: error: capture group with incompatible types
                .A, .C => |e| {
                           ^
/home/andy/downloads/zig/build/test.zig:18:17: note: type 'u8' here
                .A, .C => |e| {
                ^
/home/andy/downloads/zig/build/test.zig:18:21: note: type 'u16' here
                .A, .C => |e| {
                    ^

However, I propose this should work. peer type resolution would make the type of e be u16 and everything is fine. Likewise a T could be grouped with a ?T.

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedThis proposal is planned.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions