authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2026-01-10 14:57:23+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-01-11 11:37:17+00:00
log5a376d97d4595f12dffaf54c4cfc303b0e902cc6
tree3e6b5d1b55e379d87ae321ed74a68e643d9631d5
parent0b3b536f18957979374a00b2411943b4a37beb0f
signaturelock-open Commit is signed but in an unrecognized format.

langref: document new switch features

- switch on tagged union with runtime-captured tag - switch on errors special cases

3 files changed, 70 insertions(+), 4 deletions(-)

doc/langref.html.in+13-4
......@@ -2461,7 +2461,8 @@ or
24612461 {#header_open|Tagged union#}
24622462 <p>Unions can be declared with an enum tag type.
24632463 This turns the union into a <em>tagged</em> union, which makes it eligible
2464 to use with {#link|switch#} expressions.
2464 to use with {#link|switch#} expressions. When switching on tagged unions,
2465 the tag value can be obtained using an additional capture.
24652466 Tagged unions coerce to their tag type: {#link|Type Coercion: Unions and Enums#}.
24662467 </p>
24672468 {#code|test_tagged_union.zig#}
......@@ -2594,6 +2595,13 @@ or
25942595
25952596 {#header_close#}
25962597
2598 {#header_open|Switching on errors#}
2599 <p>
2600 When switching on errors, some special cases are allowed to simplify generic programming patterns:
2601 </p>
2602 {#code|test_switch_on_errors.zig#}
2603 {#header_close#}
2604
25972605 {#header_open|Labeled switch#}
25982606 <p>
25992607 When a switch statement is labeled, it can be referenced from a
......@@ -2659,12 +2667,13 @@ or
26592667 {#code|test_inline_else.zig#}
26602668
26612669 <p>
2662 When using an inline prong switching on an union an additional
2663 capture can be used to obtain the union's enum tag value.
2670 When using an inline prong switching on an union an additional capture
2671 can be used to obtain the union's enum tag value at comptime, even though
2672 its payload might only be known at runtime.
26642673 </p>
26652674 {#code|test_inline_switch_union_tag.zig#}
26662675
2667 {#see_also|inline while|inline for#}
2676 {#see_also|inline while|inline for|Tagged union#}
26682677 {#header_close#}
26692678 {#header_close#}
26702679
doc/langref/test_switch_on_errors.zig created+52
......@@ -0,0 +1,52 @@
1const FileOpenError0 = error{
2 AccessDenied,
3 OutOfMemory,
4 FileNotFound,
5};
6
7fn openFile0() FileOpenError0 {
8 return error.OutOfMemory;
9}
10
11test "unreachable else prong" {
12 switch (openFile0()) {
13 error.AccessDenied, error.FileNotFound => |e| return e,
14 error.OutOfMemory => {},
15 else => unreachable, // technically unreachable, but will still compile!
16 }
17
18 // Allowed unreachable else prongs are:
19 // `else => unreachable,`
20 // `else => return,`
21 // `else => |e| return e,` (where `e` is any identifier)
22}
23
24const FileOpenError1 = error{
25 AccessDenied,
26 SystemResources,
27 FileNotFound,
28};
29
30fn openFile1() FileOpenError1 {
31 return error.SystemResources;
32}
33
34fn openFileGeneric(comptime kind: u1) switch (kind) {
35 0 => FileOpenError0,
36 1 => FileOpenError1,
37} {
38 return switch (kind) {
39 0 => openFile0(),
40 1 => openFile1(),
41 };
42}
43
44test "comptime unreachable errors not in error set" {
45 switch (openFileGeneric(1)) {
46 error.AccessDenied, error.FileNotFound => |e| return e,
47 error.OutOfMemory => comptime unreachable, // not in `FileOpenError1`!
48 error.SystemResources => {},
49 }
50}
51
52// test
doc/langref/test_tagged_union.zig+5
......@@ -18,6 +18,11 @@ test "switch on tagged union" {
1818 .ok => |value| try expect(value == 42),
1919 .not_ok => unreachable,
2020 }
21
22 switch (c) {
23 .ok => |_, tag| try expect(tag == .ok),
24 .not_ok => unreachable,
25 }
2126}
2227
2328test "get tag type" {