| author | |
| committer | |
| log | 5d705fc6e35e75a604d3dbbb377ab01bf2b2b575 |
| tree | a107156cf3a48f1dace171fca865c34ae032f8f2 |
| parent | 1ca90b585692c9611c64412844d2f3a7b3e11340 |
See #10616 files changed, 109 insertions(+), 16 deletions(-)
doc/langref.html.in+24-7| ... | @@ -4919,12 +4919,15 @@ test "main" { | ... | @@ -4919,12 +4919,15 @@ test "main" { |
| 4919 | </p> | 4919 | </p> |
| 4920 | {#see_also|@import#} | 4920 | {#see_also|@import#} |
| 4921 | {#header_close#} | 4921 | {#header_close#} |
| 4922 | {#header_open|@export#} | 4922 | |
| 4923 | <pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre> | 4923 | {#header_open|@errSetCast#} |
| 4924 | <pre><code class="zig">@errSetCast(comptime T: DestType, value: var) DestType</code></pre> | ||
| 4924 | <p> | 4925 | <p> |
| 4925 | Creates a symbol in the output object file. | 4926 | Converts an error value from one error set to another error set. Attempting to convert an error |
| 4927 | which is not in the destination error set results in {#link|Undefined Behavior#}. | ||
| 4926 | </p> | 4928 | </p> |
| 4927 | {#header_close#} | 4929 | {#header_close#} |
| 4930 | |||
| 4928 | {#header_open|@errorName#} | 4931 | {#header_open|@errorName#} |
| 4929 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> | 4932 | <pre><code class="zig">@errorName(err: error) []u8</code></pre> |
| 4930 | <p> | 4933 | <p> |
| ... | @@ -4949,6 +4952,14 @@ test "main" { | ... | @@ -4949,6 +4952,14 @@ test "main" { |
| 4949 | stack trace object. Otherwise returns `null`. | 4952 | stack trace object. Otherwise returns `null`. |
| 4950 | </p> | 4953 | </p> |
| 4951 | {#header_close#} | 4954 | {#header_close#} |
| 4955 | |||
| 4956 | {#header_open|@export#} | ||
| 4957 | <pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre> | ||
| 4958 | <p> | ||
| 4959 | Creates a symbol in the output object file. | ||
| 4960 | </p> | ||
| 4961 | {#header_close#} | ||
| 4962 | |||
| 4952 | {#header_open|@fence#} | 4963 | {#header_open|@fence#} |
| 4953 | <pre><code class="zig">@fence(order: AtomicOrder)</code></pre> | 4964 | <pre><code class="zig">@fence(order: AtomicOrder)</code></pre> |
| 4954 | <p> | 4965 | <p> |
| ... | @@ -5817,10 +5828,10 @@ pub fn build(b: &Builder) void { | ... | @@ -5817,10 +5828,10 @@ pub fn build(b: &Builder) void { |
| 5817 | {#header_open|Undefined Behavior#} | 5828 | {#header_open|Undefined Behavior#} |
| 5818 | <p> | 5829 | <p> |
| 5819 | Zig has many instances of undefined behavior. If undefined behavior is | 5830 | Zig has many instances of undefined behavior. If undefined behavior is |
| 5820 | detected at compile-time, Zig emits an error. Most undefined behavior that | 5831 | detected at compile-time, Zig emits a compile error and refuses to continue. |
| 5821 | cannot be detected at compile-time can be detected at runtime. In these cases, | 5832 | Most undefined behavior that cannot be detected at compile-time can be detected |
| 5822 | Zig has safety checks. Safety checks can be disabled on a per-block basis | 5833 | at runtime. In these cases, Zig has safety checks. Safety checks can be disabled |
| 5823 | with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#} | 5834 | on a per-block basis with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#} |
| 5824 | build mode disables all safety checks in order to facilitate optimizations. | 5835 | build mode disables all safety checks in order to facilitate optimizations. |
| 5825 | </p> | 5836 | </p> |
| 5826 | <p> | 5837 | <p> |
| ... | @@ -6101,6 +6112,11 @@ comptime { | ... | @@ -6101,6 +6112,11 @@ comptime { |
| 6101 | <p>TODO</p> | 6112 | <p>TODO</p> |
| 6102 | 6113 | ||
| 6103 | {#header_close#} | 6114 | {#header_close#} |
| 6115 | |||
| 6116 | {#header_open|Invalid Error Set Cast#} | ||
| 6117 | <p>TODO</p> | ||
| 6118 | {#header_close#} | ||
| 6119 | |||
| 6104 | {#header_open|Incorrect Pointer Alignment#} | 6120 | {#header_open|Incorrect Pointer Alignment#} |
| 6105 | <p>TODO</p> | 6121 | <p>TODO</p> |
| 6106 | 6122 | ||
| ... | @@ -6109,6 +6125,7 @@ comptime { | ... | @@ -6109,6 +6125,7 @@ comptime { |
| 6109 | <p>TODO</p> | 6125 | <p>TODO</p> |
| 6110 | 6126 | ||
| 6111 | {#header_close#} | 6127 | {#header_close#} |
| 6128 | |||
| 6112 | {#header_close#} | 6129 | {#header_close#} |
| 6113 | {#header_open|Memory#} | 6130 | {#header_open|Memory#} |
| 6114 | <p>TODO: explain no default allocator in zig</p> | 6131 | <p>TODO: explain no default allocator in zig</p> |
src/all_types.hpp+9| ... | @@ -1359,6 +1359,7 @@ enum BuiltinFnId { | ... | @@ -1359,6 +1359,7 @@ enum BuiltinFnId { |
| 1359 | BuiltinFnIdTruncate, | 1359 | BuiltinFnIdTruncate, |
| 1360 | BuiltinFnIdIntCast, | 1360 | BuiltinFnIdIntCast, |
| 1361 | BuiltinFnIdFloatCast, | 1361 | BuiltinFnIdFloatCast, |
| 1362 | BuiltinFnIdErrSetCast, | ||
| 1362 | BuiltinFnIdIntToFloat, | 1363 | BuiltinFnIdIntToFloat, |
| 1363 | BuiltinFnIdFloatToInt, | 1364 | BuiltinFnIdFloatToInt, |
| 1364 | BuiltinFnIdBoolToInt, | 1365 | BuiltinFnIdBoolToInt, |
| ... | @@ -2121,6 +2122,7 @@ enum IrInstructionId { | ... | @@ -2121,6 +2122,7 @@ enum IrInstructionId { |
| 2121 | IrInstructionIdMergeErrRetTraces, | 2122 | IrInstructionIdMergeErrRetTraces, |
| 2122 | IrInstructionIdMarkErrRetTracePtr, | 2123 | IrInstructionIdMarkErrRetTracePtr, |
| 2123 | IrInstructionIdSqrt, | 2124 | IrInstructionIdSqrt, |
| 2125 | IrInstructionIdErrSetCast, | ||
| 2124 | }; | 2126 | }; |
| 2125 | 2127 | ||
| 2126 | struct IrInstruction { | 2128 | struct IrInstruction { |
| ... | @@ -2656,6 +2658,13 @@ struct IrInstructionFloatCast { | ... | @@ -2656,6 +2658,13 @@ struct IrInstructionFloatCast { |
| 2656 | IrInstruction *target; | 2658 | IrInstruction *target; |
| 2657 | }; | 2659 | }; |
| 2658 | 2660 | ||
| 2661 | struct IrInstructionErrSetCast { | ||
| 2662 | IrInstruction base; | ||
| 2663 | |||
| 2664 | IrInstruction *dest_type; | ||
| 2665 | IrInstruction *target; | ||
| 2666 | }; | ||
| 2667 | |||
| 2659 | struct IrInstructionIntToFloat { | 2668 | struct IrInstructionIntToFloat { |
| 2660 | IrInstruction base; | 2669 | IrInstruction base; |
| 2661 | 2670 |
src/codegen.cpp+2| ... | @@ -4727,6 +4727,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -4727,6 +4727,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 4727 | case IrInstructionIdIntToFloat: | 4727 | case IrInstructionIdIntToFloat: |
| 4728 | case IrInstructionIdFloatToInt: | 4728 | case IrInstructionIdFloatToInt: |
| 4729 | case IrInstructionIdBoolToInt: | 4729 | case IrInstructionIdBoolToInt: |
| 4730 | case IrInstructionIdErrSetCast: | ||
| 4730 | zig_unreachable(); | 4731 | zig_unreachable(); |
| 4731 | 4732 | ||
| 4732 | case IrInstructionIdReturn: | 4733 | case IrInstructionIdReturn: |
| ... | @@ -6356,6 +6357,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -6356,6 +6357,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 6356 | create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); | 6357 | create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); |
| 6357 | create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); | 6358 | create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); |
| 6358 | create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); | 6359 | create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); |
| 6360 | create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2); | ||
| 6359 | } | 6361 | } |
| 6360 | 6362 | ||
| 6361 | static const char *bool_to_str(bool b) { | 6363 | static const char *bool_to_str(bool b) { |
src/ir.cpp+61-7| ... | @@ -468,6 +468,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { | ... | @@ -468,6 +468,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { |
| 468 | return IrInstructionIdFloatCast; | 468 | return IrInstructionIdFloatCast; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { | ||
| 472 | return IrInstructionIdErrSetCast; | ||
| 473 | } | ||
| 474 | |||
| 471 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { | 475 | static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { |
| 472 | return IrInstructionIdIntToFloat; | 476 | return IrInstructionIdIntToFloat; |
| 473 | } | 477 | } |
| ... | @@ -1941,6 +1945,17 @@ static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1941,6 +1945,17 @@ static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode |
| 1941 | return &instruction->base; | 1945 | return &instruction->base; |
| 1942 | } | 1946 | } |
| 1943 | 1947 | ||
| 1948 | static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { | ||
| 1949 | IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); | ||
| 1950 | instruction->dest_type = dest_type; | ||
| 1951 | instruction->target = target; | ||
| 1952 | |||
| 1953 | ir_ref_instruction(dest_type, irb->current_basic_block); | ||
| 1954 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1955 | |||
| 1956 | return &instruction->base; | ||
| 1957 | } | ||
| 1958 | |||
| 1944 | static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { | 1959 | static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { |
| 1945 | IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); | 1960 | IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); |
| 1946 | instruction->dest_type = dest_type; | 1961 | instruction->dest_type = dest_type; |
| ... | @@ -4054,6 +4069,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4054,6 +4069,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4054 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); | 4069 | IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); |
| 4055 | return ir_lval_wrap(irb, scope, result, lval); | 4070 | return ir_lval_wrap(irb, scope, result, lval); |
| 4056 | } | 4071 | } |
| 4072 | case BuiltinFnIdErrSetCast: | ||
| 4073 | { | ||
| 4074 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4075 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4076 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4077 | return arg0_value; | ||
| 4078 | |||
| 4079 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4080 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4081 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4082 | return arg1_value; | ||
| 4083 | |||
| 4084 | IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); | ||
| 4085 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 4086 | } | ||
| 4057 | case BuiltinFnIdIntToFloat: | 4087 | case BuiltinFnIdIntToFloat: |
| 4058 | { | 4088 | { |
| 4059 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4089 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -10104,13 +10134,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10104,13 +10134,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10104 | } | 10134 | } |
| 10105 | 10135 | ||
| 10106 | 10136 | ||
| 10107 | // explicit error set cast | ||
| 10108 | if (wanted_type->id == TypeTableEntryIdErrorSet && | ||
| 10109 | actual_type->id == TypeTableEntryIdErrorSet) | ||
| 10110 | { | ||
| 10111 | return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type); | ||
| 10112 | } | ||
| 10113 | |||
| 10114 | // explicit cast from [N]T to []const T | 10137 | // explicit cast from [N]T to []const T |
| 10115 | if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) { | 10138 | if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) { |
| 10116 | TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; | 10139 | TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| ... | @@ -17593,6 +17616,34 @@ static TypeTableEntry *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstr | ... | @@ -17593,6 +17616,34 @@ static TypeTableEntry *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstr |
| 17593 | return dest_type; | 17616 | return dest_type; |
| 17594 | } | 17617 | } |
| 17595 | 17618 | ||
| 17619 | static TypeTableEntry *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { | ||
| 17620 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | ||
| 17621 | if (type_is_invalid(dest_type)) | ||
| 17622 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17623 | |||
| 17624 | if (dest_type->id != TypeTableEntryIdErrorSet) { | ||
| 17625 | ir_add_error(ira, instruction->dest_type, | ||
| 17626 | buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); | ||
| 17627 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17628 | } | ||
| 17629 | |||
| 17630 | IrInstruction *target = instruction->target->other; | ||
| 17631 | if (type_is_invalid(target->value.type)) | ||
| 17632 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17633 | |||
| 17634 | if (target->value.type->id != TypeTableEntryIdErrorSet) { | ||
| 17635 | ir_add_error(ira, instruction->target, | ||
| 17636 | buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value.type->name))); | ||
| 17637 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17638 | } | ||
| 17639 | |||
| 17640 | IrInstruction *result = ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); | ||
| 17641 | if (type_is_invalid(result->value.type)) | ||
| 17642 | return ira->codegen->builtin_types.entry_invalid; | ||
| 17643 | ir_link_new_instruction(result, &instruction->base); | ||
| 17644 | return dest_type; | ||
| 17645 | } | ||
| 17646 | |||
| 17596 | static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { | 17647 | static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { |
| 17597 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); | 17648 | TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); |
| 17598 | if (type_is_invalid(dest_type)) | 17649 | if (type_is_invalid(dest_type)) |
| ... | @@ -20193,6 +20244,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -20193,6 +20244,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 20193 | return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); | 20244 | return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); |
| 20194 | case IrInstructionIdFloatCast: | 20245 | case IrInstructionIdFloatCast: |
| 20195 | return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); | 20246 | return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); |
| 20247 | case IrInstructionIdErrSetCast: | ||
| 20248 | return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); | ||
| 20196 | case IrInstructionIdIntToFloat: | 20249 | case IrInstructionIdIntToFloat: |
| 20197 | return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); | 20250 | return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); |
| 20198 | case IrInstructionIdFloatToInt: | 20251 | case IrInstructionIdFloatToInt: |
| ... | @@ -20544,6 +20597,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -20544,6 +20597,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 20544 | case IrInstructionIdAtomicLoad: | 20597 | case IrInstructionIdAtomicLoad: |
| 20545 | case IrInstructionIdIntCast: | 20598 | case IrInstructionIdIntCast: |
| 20546 | case IrInstructionIdFloatCast: | 20599 | case IrInstructionIdFloatCast: |
| 20600 | case IrInstructionIdErrSetCast: | ||
| 20547 | case IrInstructionIdIntToFloat: | 20601 | case IrInstructionIdIntToFloat: |
| 20548 | case IrInstructionIdFloatToInt: | 20602 | case IrInstructionIdFloatToInt: |
| 20549 | case IrInstructionIdBoolToInt: | 20603 | case IrInstructionIdBoolToInt: |
src/ir_print.cpp+11| ... | @@ -664,6 +664,14 @@ static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instructio | ... | @@ -664,6 +664,14 @@ static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instructio |
| 664 | fprintf(irp->f, ")"); | 664 | fprintf(irp->f, ")"); |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | static void ir_print_err_set_cast(IrPrint *irp, IrInstructionErrSetCast *instruction) { | ||
| 668 | fprintf(irp->f, "@errSetCast("); | ||
| 669 | ir_print_other_instruction(irp, instruction->dest_type); | ||
| 670 | fprintf(irp->f, ", "); | ||
| 671 | ir_print_other_instruction(irp, instruction->target); | ||
| 672 | fprintf(irp->f, ")"); | ||
| 673 | } | ||
| 674 | |||
| 667 | static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) { | 675 | static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) { |
| 668 | fprintf(irp->f, "@intToFloat("); | 676 | fprintf(irp->f, "@intToFloat("); |
| 669 | ir_print_other_instruction(irp, instruction->dest_type); | 677 | ir_print_other_instruction(irp, instruction->dest_type); |
| ... | @@ -1461,6 +1469,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1461,6 +1469,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1461 | case IrInstructionIdFloatCast: | 1469 | case IrInstructionIdFloatCast: |
| 1462 | ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction); | 1470 | ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction); |
| 1463 | break; | 1471 | break; |
| 1472 | case IrInstructionIdErrSetCast: | ||
| 1473 | ir_print_err_set_cast(irp, (IrInstructionErrSetCast *)instruction); | ||
| 1474 | break; | ||
| 1464 | case IrInstructionIdIntToFloat: | 1475 | case IrInstructionIdIntToFloat: |
| 1465 | ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction); | 1476 | ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction); |
| 1466 | break; | 1477 | break; |
test/cases/error.zig+2-2| ... | @@ -124,8 +124,8 @@ const Set2 = error{ | ... | @@ -124,8 +124,8 @@ const Set2 = error{ |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | fn testExplicitErrorSetCast(set1: Set1) void { | 126 | fn testExplicitErrorSetCast(set1: Set1) void { |
| 127 | var x = Set2(set1); | 127 | var x = @errSetCast(Set2, set1); |
| 128 | var y = Set1(x); | 128 | var y = @errSetCast(Set1, x); |
| 129 | assert(y == error.A); | 129 | assert(y == error.A); |
| 130 | } | 130 | } |
| 131 | 131 |