zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 5a376d97d4595f12dffaf54c4cfc303b0e902cc6 (tree)
parent 0b3b536f18957979374a00b2411943b4a37beb0f
Author: Justus Klausecker <justus@klausecker.de>
Date:   Sat, 10 Jan 2026 14:57:23 +0100

langref: document new switch features

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

Diffstat:
Mdoc/langref.html.in | 17+++++++++++++----
Adoc/langref/test_switch_on_errors.zig | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/langref/test_tagged_union.zig | 5+++++
3 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/doc/langref.html.in b/doc/langref.html.in @@ -2461,7 +2461,8 @@ or {#header_open|Tagged union#} <p>Unions can be declared with an enum tag type. This turns the union into a <em>tagged</em> union, which makes it eligible - to use with {#link|switch#} expressions. + to use with {#link|switch#} expressions. When switching on tagged unions, + the tag value can be obtained using an additional capture. Tagged unions coerce to their tag type: {#link|Type Coercion: Unions and Enums#}. </p> {#code|test_tagged_union.zig#} @@ -2594,6 +2595,13 @@ or {#header_close#} + {#header_open|Switching on errors#} + <p> + When switching on errors, some special cases are allowed to simplify generic programming patterns: + </p> + {#code|test_switch_on_errors.zig#} + {#header_close#} + {#header_open|Labeled switch#} <p> When a switch statement is labeled, it can be referenced from a @@ -2659,12 +2667,13 @@ or {#code|test_inline_else.zig#} <p> - When using an inline prong switching on an union an additional - capture can be used to obtain the union's enum tag value. + When using an inline prong switching on an union an additional capture + can be used to obtain the union's enum tag value at comptime, even though + its payload might only be known at runtime. </p> {#code|test_inline_switch_union_tag.zig#} - {#see_also|inline while|inline for#} + {#see_also|inline while|inline for|Tagged union#} {#header_close#} {#header_close#} diff --git a/doc/langref/test_switch_on_errors.zig b/doc/langref/test_switch_on_errors.zig @@ -0,0 +1,52 @@ +const FileOpenError0 = error{ + AccessDenied, + OutOfMemory, + FileNotFound, +}; + +fn openFile0() FileOpenError0 { + return error.OutOfMemory; +} + +test "unreachable else prong" { + switch (openFile0()) { + error.AccessDenied, error.FileNotFound => |e| return e, + error.OutOfMemory => {}, + else => unreachable, // technically unreachable, but will still compile! + } + + // Allowed unreachable else prongs are: + // `else => unreachable,` + // `else => return,` + // `else => |e| return e,` (where `e` is any identifier) +} + +const FileOpenError1 = error{ + AccessDenied, + SystemResources, + FileNotFound, +}; + +fn openFile1() FileOpenError1 { + return error.SystemResources; +} + +fn openFileGeneric(comptime kind: u1) switch (kind) { + 0 => FileOpenError0, + 1 => FileOpenError1, +} { + return switch (kind) { + 0 => openFile0(), + 1 => openFile1(), + }; +} + +test "comptime unreachable errors not in error set" { + switch (openFileGeneric(1)) { + error.AccessDenied, error.FileNotFound => |e| return e, + error.OutOfMemory => comptime unreachable, // not in `FileOpenError1`! + error.SystemResources => {}, + } +} + +// test diff --git a/doc/langref/test_tagged_union.zig b/doc/langref/test_tagged_union.zig @@ -18,6 +18,11 @@ test "switch on tagged union" { .ok => |value| try expect(value == 42), .not_ok => unreachable, } + + switch (c) { + .ok => |_, tag| try expect(tag == .ok), + .not_ok => unreachable, + } } test "get tag type" {