| ... | ... | @@ -2782,30 +2782,96 @@ test "fn reflection" { |
| 2782 | 2782 | {#header_close#} |
| 2783 | 2783 | {#header_close#} |
| 2784 | 2784 | {#header_open|Errors#} |
| 2785 | {#header_open|Error Set Type#} |
| 2785 | 2786 | <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. |
| 2787 | 2791 | </p> |
| 2788 | 2792 | <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>. |
| 2790 | 2795 | </p> |
| 2791 | 2796 | <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: |
| 2795 | 2798 | </p> |
| 2799 | {#code_begin|test#} |
| 2800 | const std = @import("std"); |
| 2801 | |
| 2802 | const FileOpenError = error { |
| 2803 | AccessDenied, |
| 2804 | OutOfMemory, |
| 2805 | FileNotFound, |
| 2806 | }; |
| 2807 | |
| 2808 | const AllocationError = error { |
| 2809 | OutOfMemory, |
| 2810 | }; |
| 2811 | |
| 2812 | test "implicit cast subset to superset" { |
| 2813 | const err = foo(AllocationError.OutOfMemory); |
| 2814 | std.debug.assert(err == FileOpenError.OutOfMemory); |
| 2815 | } |
| 2816 | |
| 2817 | fn foo(err: AllocationError) FileOpenError { |
| 2818 | return err; |
| 2819 | } |
| 2820 | {#code_end#} |
| 2796 | 2821 | <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#} |
| 2825 | const FileOpenError = error { |
| 2826 | AccessDenied, |
| 2827 | OutOfMemory, |
| 2828 | FileNotFound, |
| 2829 | }; |
| 2830 | |
| 2831 | const AllocationError = error { |
| 2832 | OutOfMemory, |
| 2833 | }; |
| 2834 | |
| 2835 | test "implicit cast superset to subset" { |
| 2836 | foo(FileOpenError.OutOfMemory) catch {}; |
| 2837 | } |
| 2838 | |
| 2839 | fn 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#} |
| 2847 | const err = error.FileNotFound; |
| 2848 | {#code_end#} |
| 2849 | <p>This is equivalent to:</p> |
| 2850 | {#code_begin|syntax#} |
| 2851 | const 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. |
| 2799 | 2860 | </p> |
| 2800 | 2861 | <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. |
| 2803 | 2865 | </p> |
| 2804 | 2866 | <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#}. |
| 2807 | 2871 | </p> |
| 2808 | | {#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#} |
| 2872 | {#header_close#} |
| 2873 | {#header_close#} |
| 2874 | {#header_open|Error Union Type#} |
| 2809 | 2875 | <p> |
| 2810 | 2876 | Most of the time you will not find yourself using an error set type. Instead, |
| 2811 | 2877 | 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 { |
| 2918 | 2984 | a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the |
| 2919 | 2985 | application, if there <em>was</em> a surprise error here, the application would crash |
| 2920 | 2986 | appropriately. |
| 2921 | | TODO: mention error return traces |
| 2922 | 2987 | </p> |
| 2923 | 2988 | <p> |
| 2924 | 2989 | 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 { |
| 2986 | 3051 | </li> |
| 2987 | 3052 | </ul> |
| 2988 | 3053 | {#see_also|defer|if|switch#} |
| 2989 | | {#header_open|Error Union Type#} |
| 3054 | |
| 2990 | 3055 | <p>An error union is created with the <code>!</code> binary operator. |
| 2991 | 3056 | You can use compile-time reflection to access the child type of an error union:</p> |
| 2992 | 3057 | {#code_begin|test#} |
| ... | ... | @@ -3008,8 +3073,12 @@ test "error union" { |
| 3008 | 3073 | comptime assert(@typeOf(foo).ErrorSet == error); |
| 3009 | 3074 | } |
| 3010 | 3075 | {#code_end#} |
| 3076 | <p>TODO the <code>||</code> operator for error sets</p> |
| 3077 | {#header_open|Inferred Error Sets#} |
| 3078 | <p>TODO</p> |
| 3011 | 3079 | {#header_close#} |
| 3012 | | {#header_open|Error Set Type#} |
| 3080 | {#header_close#} |
| 3081 | {#header_open|Error Return Traces#} |
| 3013 | 3082 | <p>TODO</p> |
| 3014 | 3083 | {#header_close#} |
| 3015 | 3084 | {#header_close#} |