| 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 | 2973 | A: u32, |
| 2974 | 2974 | C: Point, |
| 2975 | 2975 | D, |
| 2976 | E: u32, | |
| 2976 | 2977 | }; |
| 2977 | 2978 | |
| 2978 | 2979 | var a = Item{ .C = Point{ .x = 1, .y = 2 } }; |
| ... | ... | @@ -2980,8 +2981,9 @@ test "switch on tagged union" { |
| 2980 | 2981 | // Switching on more complex enums is allowed. |
| 2981 | 2982 | const b = switch (a) { |
| 2982 | 2983 | // 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, | |
| 2985 | 2987 | |
| 2986 | 2988 | // A reference to the matched value can be obtained using `*` syntax. |
| 2987 | 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 | 19160 | if (field->type_entry != payload) { |
| 19161 | 19161 | if (!invalid_payload) { |
| 19162 | 19162 | 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)); | |
| 19165 | 19165 | } |
| 19166 | 19166 | |
| 19167 | 19167 | if (i == instruction->prongs_len - 1) |
test/compile_errors.zig+17| ... | ... | @@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6048 | 6048 | "tmp.zig:5:30: error: expression value is ignored", |
| 6049 | 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 | 391 | S.doTheTest(1); |
| 392 | 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 | } |