| author | |
| committer | |
| log | a1b952f4b03b7becad85ad47f96a75c0be620cf8 |
| tree | 3f768d24855ae5183d5a9835a07eda7e969de948 |
| parent | 2d85ff94653457ea12cd9ab0984ab3b13c9b41e5 |
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 | }; |
| 2977 | 2978 | ||
| 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 enum | 2983 | // 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, | ||
| 2985 | 2987 | ||
| 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 | } |
| 19166 | 19166 | ||
| 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 | |||
| 395 | test "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 | } |