authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-23 20:43:47-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-23 20:43:47-05:00
log8db7a1420f892deb4a2a3c63b1a3227b65aadccf
treebe7d2b8900648a44b8413d51077ae83fb8c09f58
parentb66547e98c9034e52c5647735b47dc24939c8d15

update errors section of docs

closes #768

1 files changed, 84 insertions(+), 15 deletions(-)

doc/langref.html.in+84-15
......@@ -2782,30 +2782,96 @@ test "fn reflection" {
27822782 {#header_close#}
27832783 {#header_close#}
27842784 {#header_open|Errors#}
2785 {#header_open|Error Set Type#}
27852786 <p>
2786 One of the distinguishing features of Zig is its exception handling strategy.
2787 An error set is like an {#link|enum#}.
2788 However, each error name across the entire compilation gets assigned an unsigned integer
2789 greater than 0. You are allowed to declare the same error name more than once, and if you do, it
2790 gets assigned the same integer value.
27872791 </p>
27882792 <p>
2789 TODO rewrite the errors section to take into account error sets
2793 The number of unique error values across the entire compilation should determine the size of the error set type.
2794 However right now it is hard coded to be a <code>u16</code>. See <a href="https://github.com/zig-lang/zig/issues/786">#768</a>.
27902795 </p>
27912796 <p>
2792 These error values are assigned an unsigned integer value greater than 0 at
2793 compile time. You are allowed to declare the same error value more than once,
2794 and if you do, it gets assigned the same integer value.
2797 You can implicitly cast an error from a subset to its superset:
27952798 </p>
2799 {#code_begin|test#}
2800const std = @import("std");
2801
2802const FileOpenError = error {
2803 AccessDenied,
2804 OutOfMemory,
2805 FileNotFound,
2806};
2807
2808const AllocationError = error {
2809 OutOfMemory,
2810};
2811
2812test "implicit cast subset to superset" {
2813 const err = foo(AllocationError.OutOfMemory);
2814 std.debug.assert(err == FileOpenError.OutOfMemory);
2815}
2816
2817fn foo(err: AllocationError) FileOpenError {
2818 return err;
2819}
2820 {#code_end#}
27962821 <p>
2797 You can refer to these error values with the error namespace such as
2798 <code>error.FileNotFound</code>.
2822 But you cannot implicitly cast an error from a superset to a subset:
2823 </p>
2824 {#code_begin|test_err|not a member of destination error set#}
2825const FileOpenError = error {
2826 AccessDenied,
2827 OutOfMemory,
2828 FileNotFound,
2829};
2830
2831const AllocationError = error {
2832 OutOfMemory,
2833};
2834
2835test "implicit cast superset to subset" {
2836 foo(FileOpenError.OutOfMemory) catch {};
2837}
2838
2839fn foo(err: FileOpenError) AllocationError {
2840 return err;
2841}
2842 {#code_end#}
2843 <p>
2844 There is a shortcut for declaring an error set with only 1 value, and then getting that value:
2845 </p>
2846 {#code_begin|syntax#}
2847const err = error.FileNotFound;
2848 {#code_end#}
2849 <p>This is equivalent to:</p>
2850 {#code_begin|syntax#}
2851const err = (error {FileNotFound}).FileNotFound;
2852 {#code_end#}
2853 <p>
2854 This becomes useful when using {#link|Inferred Error Sets#}.
2855 </p>
2856 {#header_open|The Global Error Set#}
2857 <p><code>error</code> refers to the global error set.
2858 This is the error set that contains all errors in the entire compilation unit.
2859 It is a superset of all other error sets and a subset of none of them.
27992860 </p>
28002861 <p>
2801 Each error value across the entire compilation unit gets a unique integer,
2802 and this determines the size of the error set type.
2862 You can implicitly cast any error set to the global one, and you can explicitly
2863 cast an error of global error set to a non-global one. This inserts a language-level
2864 assert to make sure the error value is in fact in the destination error set.
28032865 </p>
28042866 <p>
2805 The error set type is one of the error values, and in the same way that pointers
2806 cannot be null, a error set instance is always an error.
2867 The global error set should generally be avoided when possible, because it prevents
2868 the compiler from knowing what errors are possible at compile-time. Knowing
2869 the error set at compile-time is better for generated documentationt and for
2870 helpful error messages such as forgetting a possible error value in a {#link|switch#}.
28072871 </p>
2808 {#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#}
2872 {#header_close#}
2873 {#header_close#}
2874 {#header_open|Error Union Type#}
28092875 <p>
28102876 Most of the time you will not find yourself using an error set type. Instead,
28112877 likely you will be using the error union type. This is when you take an error set
......@@ -2918,7 +2984,6 @@ fn doAThing(str: []u8) !void {
29182984 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the
29192985 application, if there <em>was</em> a surprise error here, the application would crash
29202986 appropriately.
2921 TODO: mention error return traces
29222987 </p>
29232988 <p>
29242989 Finally, you may want to take a different action for every situation. For that, we combine
......@@ -2986,7 +3051,7 @@ fn createFoo(param: i32) !Foo {
29863051 </li>
29873052 </ul>
29883053 {#see_also|defer|if|switch#}
2989 {#header_open|Error Union Type#}
3054
29903055 <p>An error union is created with the <code>!</code> binary operator.
29913056 You can use compile-time reflection to access the child type of an error union:</p>
29923057 {#code_begin|test#}
......@@ -3008,8 +3073,12 @@ test "error union" {
30083073 comptime assert(@typeOf(foo).ErrorSet == error);
30093074}
30103075 {#code_end#}
3076 <p>TODO the <code>||</code> operator for error sets</p>
3077 {#header_open|Inferred Error Sets#}
3078 <p>TODO</p>
30113079 {#header_close#}
3012 {#header_open|Error Set Type#}
3080 {#header_close#}
3081 {#header_open|Error Return Traces#}
30133082 <p>TODO</p>
30143083 {#header_close#}
30153084 {#header_close#}