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" {...@@ -2973,6 +2973,7 @@ test "switch on tagged union" {
2973 A: u32,2973 A: u32,
2974 C: Point,2974 C: Point,
2975 D,2975 D,
2976 E: u32,
2976 };2977 };
29772978
2978 var a = Item{ .C = Point{ .x = 1, .y = 2 } };2979 var a = Item{ .C = Point{ .x = 1, .y = 2 } };
...@@ -2980,8 +2981,9 @@ test "switch on tagged union" {...@@ -2980,8 +2981,9 @@ test "switch on tagged union" {
2980 // Switching on more complex enums is allowed.2981 // Switching on more complex enums is allowed.
2981 const b = switch (a) {2982 const b = switch (a) {
2982 // A capture group is allowed on a match, and will return the enum2983 // A capture group is allowed on a match, and will return the enum
2983 // value matched.2984 // value matched. If the payloads of both cases are the same
2984 Item.A => |item| item,2985 // they can be put into the same switch prong.
2986 Item.A, Item.E => |item| item,
29852987
2986 // A reference to the matched value can be obtained using `*` syntax.2988 // A reference to the matched value can be obtained using `*` syntax.
2987 Item.C => |*item| blk: {2989 Item.C => |*item| blk: {
src/ir.cpp+2-2
...@@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru...@@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
19160 if (field->type_entry != payload) {19160 if (field->type_entry != payload) {
19161 if (!invalid_payload) {19161 if (!invalid_payload) {
19162 invalid_payload = ir_add_error(ira, &instruction->base,19162 invalid_payload = ir_add_error(ira, &instruction->base,
19163 buf_sprintf("switch prong contains cases with differing payloads"));19163 buf_sprintf("switch prong contains cases with different payloads"));
19164 invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name));19164 invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name));
19165 }19165 }
1916619166
19167 if (i == instruction->prongs_len - 1)19167 if (i == instruction->prongs_len - 1)
test/compile_errors.zig+17
...@@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6048 "tmp.zig:5:30: error: expression value is ignored",6048 "tmp.zig:5:30: error: expression value is ignored",
6049 "tmp.zig:9:30: error: expression value is ignored",6049 "tmp.zig:9:30: error: expression value is ignored",
6050 );6050 );
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 );
6051}6068}
test/stage1/behavior/switch.zig+18
...@@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" {...@@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" {
391 S.doTheTest(1);391 S.doTheTest(1);
392 comptime S.doTheTest(1);392 comptime S.doTheTest(1);
393}393}
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}