From 5a376d97d4595f12dffaf54c4cfc303b0e902cc6 Mon Sep 17 00:00:00 2001 From: Justus Klausecker Date: Sat, 10 Jan 2026 14:57:23 +0100 Subject: [PATCH] langref: document new switch features - switch on tagged union with runtime-captured tag - switch on errors special cases --- doc/langref.html.in | 17 ++++++--- doc/langref/test_switch_on_errors.zig | 52 +++++++++++++++++++++++++++ doc/langref/test_tagged_union.zig | 5 +++ 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 doc/langref/test_switch_on_errors.zig diff --git a/doc/langref.html.in b/doc/langref.html.in index f2508e175b9469ba010c2ad811caaf45bb941e15..07a5b39f2fde70651c11a272d2fb8f376ec49645 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2461,7 +2461,8 @@ or {#header_open|Tagged union#}

Unions can be declared with an enum tag type. This turns the union into a tagged 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#}.

{#code|test_tagged_union.zig#} @@ -2594,6 +2595,13 @@ or {#header_close#} + {#header_open|Switching on errors#} +

+ When switching on errors, some special cases are allowed to simplify generic programming patterns: +

+ {#code|test_switch_on_errors.zig#} + {#header_close#} + {#header_open|Labeled switch#}

When a switch statement is labeled, it can be referenced from a @@ -2659,12 +2667,13 @@ or {#code|test_inline_else.zig#}

- 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.

{#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 new file mode 100644 index 0000000000000000000000000000000000000000..7fe534e7a3bc9cfaff751847bc85431e1ba28758 --- /dev/null +++ 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 index dbe765f5b8321bee3c598778b730de89bdb0913a..58df9dc38df05c7fd29a55eb77d5385449e549c2 100644 --- 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" { -- 2.54.0