Commit a1b952f4b0

emekoi <emekankurumeh@outlook.com>
2019-07-03 20:12:14
added tests for #1107 and a note in the reference
1 parent 2d85ff9
Changed files (4)
doc/langref.html.in
@@ -2973,6 +2973,7 @@ test "switch on tagged union" {
         A: u32,
         C: Point,
         D,
+        E: u32,
     };
 
     var a = Item{ .C = Point{ .x = 1, .y = 2 } };
@@ -2980,8 +2981,9 @@ test "switch on tagged union" {
     // Switching on more complex enums is allowed.
     const b = switch (a) {
         // A capture group is allowed on a match, and will return the enum
-        // value matched.
-        Item.A => |item| item,
+        // value matched. If the payloads of both cases are the same
+        // they can be put into the same switch prong.
+        Item.A, Item.E => |item| item,
 
         // A reference to the matched value can be obtained using `*` syntax.
         Item.C => |*item| blk: {
src/ir.cpp
@@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
                 if (field->type_entry != payload) {
                     if (!invalid_payload) {
                         invalid_payload = ir_add_error(ira, &instruction->base,
-                            buf_sprintf("switch prong contains cases with differing payloads"));
-                        invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name));
+                            buf_sprintf("switch prong contains cases with different payloads"));
+                        invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name));
                     }
 
                     if (i == instruction->prongs_len - 1)
test/stage1/behavior/switch.zig
@@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" {
     S.doTheTest(1);
     comptime S.doTheTest(1);
 }
+
+test "switch prongs with cases with identical payloads" {
+    const Union = union(enum) {
+        A: usize,
+        B: isize,
+        C: usize,
+    };
+    const S = struct {
+        fn doTheTest(u: Union) void {
+            switch (u) {
+                .A, .C => |e| expect(@typeOf(e) == usize),
+                .B => |e| expect(@typeOf(e) == isize),
+            }
+        }
+    };
+    S.doTheTest(Union{ .A = 8 });
+    comptime S.doTheTest(Union{ .B = -8 });
+}
test/compile_errors.zig
@@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:5:30: error: expression value is ignored",
         "tmp.zig:9:30: error: expression value is ignored",
     );
+
+    cases.add(
+        "capture group on switch prong with different payloads",
+        \\const Union = union(enum) {
+        \\    A: usize,
+        \\    B: isize,
+        \\};
+        \\comptime {
+        \\    var u = Union{ .A = 8 };
+        \\    switch (u) {
+        \\        .A, .B => |e| unreachable,
+        \\    }
+        \\}
+    ,
+        "tmp.zig:8:20: error: switch prong contains cases with different payloads",
+        "tmp.zig:8:20: note: payload types are usize and isize",
+    );
 }