authorgravatar for emekankurumeh@outlook.comemekoi <emekankurumeh@outlook.com> 2019-07-03 13:12:14-05:00
committergravatar for emekankurumeh@outlook.comemekoi <emekankurumeh@outlook.com> 2019-07-03 13:12:14-05:00
loga1b952f4b03b7becad85ad47f96a75c0be620cf8
tree3f768d24855ae5183d5a9835a07eda7e969de948
parent2d85ff94653457ea12cd9ab0984ab3b13c9b41e5

added tests for #1107 and a note in the reference


4 files changed, 41 insertions(+), 4 deletions(-)

doc/langref.html.in+4-2
......@@ -2973,6 +2973,7 @@ test "switch on tagged union" {
29732973 A: u32,
29742974 C: Point,
29752975 D,
2976 E: u32,
29762977 };
29772978
29782979 var a = Item{ .C = Point{ .x = 1, .y = 2 } };
......@@ -2980,8 +2981,9 @@ test "switch on tagged union" {
29802981 // Switching on more complex enums is allowed.
29812982 const b = switch (a) {
29822983 // A capture group is allowed on a match, and will return the enum
2983 // value matched.
2984 Item.A => |item| item,
2984 // value matched. If the payloads of both cases are the same
2985 // they can be put into the same switch prong.
2986 Item.A, Item.E => |item| item,
29852987
29862988 // A reference to the matched value can be obtained using `*` syntax.
29872989 Item.C => |*item| blk: {
src/ir.cpp+2-2
......@@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
1916019160 if (field->type_entry != payload) {
1916119161 if (!invalid_payload) {
1916219162 invalid_payload = ir_add_error(ira, &instruction->base,
19163 buf_sprintf("switch prong contains cases with differing payloads"));
19164 invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name));
19163 buf_sprintf("switch prong contains cases with different payloads"));
19164 invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name));
1916519165 }
1916619166
1916719167 if (i == instruction->prongs_len - 1)
test/compile_errors.zig+17
......@@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
60486048 "tmp.zig:5:30: error: expression value is ignored",
60496049 "tmp.zig:9:30: error: expression value is ignored",
60506050 );
6051
6052 cases.add(
6053 "capture group on switch prong with different payloads",
6054 \\const Union = union(enum) {
6055 \\ A: usize,
6056 \\ B: isize,
6057 \\};
6058 \\comptime {
6059 \\ var u = Union{ .A = 8 };
6060 \\ switch (u) {
6061 \\ .A, .B => |e| unreachable,
6062 \\ }
6063 \\}
6064 ,
6065 "tmp.zig:8:20: error: switch prong contains cases with different payloads",
6066 "tmp.zig:8:20: note: payload types are usize and isize",
6067 );
60516068}
test/stage1/behavior/switch.zig+18
......@@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" {
391391 S.doTheTest(1);
392392 comptime S.doTheTest(1);
393393}
394
395test "switch prongs with cases with identical payloads" {
396 const Union = union(enum) {
397 A: usize,
398 B: isize,
399 C: usize,
400 };
401 const S = struct {
402 fn doTheTest(u: Union) void {
403 switch (u) {
404 .A, .C => |e| expect(@typeOf(e) == usize),
405 .B => |e| expect(@typeOf(e) == isize),
406 }
407 }
408 };
409 S.doTheTest(Union{ .A = 8 });
410 comptime S.doTheTest(Union{ .B = -8 });
411}