authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 15:01:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 15:01:42-04:00
log5d705fc6e35e75a604d3dbbb377ab01bf2b2b575
treea107156cf3a48f1dace171fca865c34ae032f8f2
parent1ca90b585692c9611c64412844d2f3a7b3e11340

remove error set casting syntax. add `@errSetCast`

See #1061

6 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 is5830 Zig has many instances of undefined behavior. If undefined behavior is
5820 detected at compile-time, Zig emits an error. Most undefined behavior that5831 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 basis5833 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>
61026113
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>
61066122
...@@ -6109,6 +6125,7 @@ comptime {...@@ -6109,6 +6125,7 @@ comptime {
6109 <p>TODO</p>6125 <p>TODO</p>
61106126
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};
21252127
2126struct IrInstruction {2128struct IrInstruction {
...@@ -2656,6 +2658,13 @@ struct IrInstructionFloatCast {...@@ -2656,6 +2658,13 @@ struct IrInstructionFloatCast {
2656 IrInstruction *target;2658 IrInstruction *target;
2657};2659};
26582660
2661struct IrInstructionErrSetCast {
2662 IrInstruction base;
2663
2664 IrInstruction *dest_type;
2665 IrInstruction *target;
2666};
2667
2659struct IrInstructionIntToFloat {2668struct IrInstructionIntToFloat {
2660 IrInstruction base;2669 IrInstruction base;
26612670
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();
47314732
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}
63606362
6361static const char *bool_to_str(bool b) {6363static 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}
470470
471static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) {
472 return IrInstructionIdErrSetCast;
473}
474
471static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) {475static 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}
19431947
1948static 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
1944static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {1959static 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 }
1010510135
1010610136
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 T10137 // 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}
1759517618
17619static 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
17596static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) {17647static 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}
666666
667static 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
667static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) {675static 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};
125125
126fn testExplicitErrorSetCast(set1: Set1) void {126fn 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}
131131