diff --git a/doc/langref.html.in b/doc/langref.html.in index f2508e175b..07a5b39f2f 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 0000000000..7fe534e7a3 --- /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 dbe765f5b8..58df9dc38d 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" {