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" {
49194919 </p>
49204920 {#see_also|@import#}
49214921 {#header_close#}
4922 {#header_open|@export#}
4923 <pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre>
4922
4923 {#header_open|@errSetCast#}
4924 <pre><code class="zig">@errSetCast(comptime T: DestType, value: var) DestType</code></pre>
49244925 <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#}.
49264928 </p>
49274929 {#header_close#}
4930
49284931 {#header_open|@errorName#}
49294932 <pre><code class="zig">@errorName(err: error) []u8</code></pre>
49304933 <p>
......@@ -4949,6 +4952,14 @@ test "main" {
49494952 stack trace object. Otherwise returns `null`.
49504953 </p>
49514954 {#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
49524963 {#header_open|@fence#}
49534964 <pre><code class="zig">@fence(order: AtomicOrder)</code></pre>
49544965 <p>
......@@ -5817,10 +5828,10 @@ pub fn build(b: &Builder) void {
58175828 {#header_open|Undefined Behavior#}
58185829 <p>
58195830 Zig has many instances of undefined behavior. If undefined behavior is
5820 detected at compile-time, Zig emits an error. Most undefined behavior that
5821 cannot be detected at compile-time can be detected at runtime. In these cases,
5822 Zig has safety checks. Safety checks can be disabled on a per-block basis
5823 with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#}
5831 detected at compile-time, Zig emits a compile error and refuses to continue.
5832 Most undefined behavior that cannot be detected at compile-time can be detected
5833 at runtime. In these cases, Zig has safety checks. Safety checks can be disabled
5834 on a per-block basis with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#}
58245835 build mode disables all safety checks in order to facilitate optimizations.
58255836 </p>
58265837 <p>
......@@ -6101,6 +6112,11 @@ comptime {
61016112 <p>TODO</p>
61026113
61036114 {#header_close#}
6115
6116 {#header_open|Invalid Error Set Cast#}
6117 <p>TODO</p>
6118 {#header_close#}
6119
61046120 {#header_open|Incorrect Pointer Alignment#}
61056121 <p>TODO</p>
61066122
......@@ -6109,6 +6125,7 @@ comptime {
61096125 <p>TODO</p>
61106126
61116127 {#header_close#}
6128
61126129 {#header_close#}
61136130 {#header_open|Memory#}
61146131 <p>TODO: explain no default allocator in zig</p>
src/all_types.hpp+9
......@@ -1359,6 +1359,7 @@ enum BuiltinFnId {
13591359 BuiltinFnIdTruncate,
13601360 BuiltinFnIdIntCast,
13611361 BuiltinFnIdFloatCast,
1362 BuiltinFnIdErrSetCast,
13621363 BuiltinFnIdIntToFloat,
13631364 BuiltinFnIdFloatToInt,
13641365 BuiltinFnIdBoolToInt,
......@@ -2121,6 +2122,7 @@ enum IrInstructionId {
21212122 IrInstructionIdMergeErrRetTraces,
21222123 IrInstructionIdMarkErrRetTracePtr,
21232124 IrInstructionIdSqrt,
2125 IrInstructionIdErrSetCast,
21242126};
21252127
21262128struct IrInstruction {
......@@ -2656,6 +2658,13 @@ struct IrInstructionFloatCast {
26562658 IrInstruction *target;
26572659};
26582660
2661struct IrInstructionErrSetCast {
2662 IrInstruction base;
2663
2664 IrInstruction *dest_type;
2665 IrInstruction *target;
2666};
2667
26592668struct IrInstructionIntToFloat {
26602669 IrInstruction base;
26612670
src/codegen.cpp+2
......@@ -4727,6 +4727,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
47274727 case IrInstructionIdIntToFloat:
47284728 case IrInstructionIdFloatToInt:
47294729 case IrInstructionIdBoolToInt:
4730 case IrInstructionIdErrSetCast:
47304731 zig_unreachable();
47314732
47324733 case IrInstructionIdReturn:
......@@ -6356,6 +6357,7 @@ static void define_builtin_fns(CodeGen *g) {
63566357 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
63576358 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
63586359 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
6360 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
63596361}
63606362
63616363static const char *bool_to_str(bool b) {
src/ir.cpp+61-7
......@@ -468,6 +468,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) {
468468 return IrInstructionIdFloatCast;
469469}
470470
471static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) {
472 return IrInstructionIdErrSetCast;
473}
474
471475static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) {
472476 return IrInstructionIdIntToFloat;
473477}
......@@ -1941,6 +1945,17 @@ static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode
19411945 return &instruction->base;
19421946}
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
19441959static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {
19451960 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node);
19461961 instruction->dest_type = dest_type;
......@@ -4054,6 +4069,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40544069 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);
40554070 return ir_lval_wrap(irb, scope, result, lval);
40564071 }
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 }
40574087 case BuiltinFnIdIntToFloat:
40584088 {
40594089 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
1010410134 }
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
1011410137 // explicit cast from [N]T to []const T
1011510138 if (is_slice(wanted_type) && actual_type->id == TypeTableEntryIdArray) {
1011610139 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
1759317616 return dest_type;
1759417617}
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
1759617647static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) {
1759717648 TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other);
1759817649 if (type_is_invalid(dest_type))
......@@ -20193,6 +20244,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
2019320244 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction);
2019420245 case IrInstructionIdFloatCast:
2019520246 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction);
20247 case IrInstructionIdErrSetCast:
20248 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction);
2019620249 case IrInstructionIdIntToFloat:
2019720250 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction);
2019820251 case IrInstructionIdFloatToInt:
......@@ -20544,6 +20597,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2054420597 case IrInstructionIdAtomicLoad:
2054520598 case IrInstructionIdIntCast:
2054620599 case IrInstructionIdFloatCast:
20600 case IrInstructionIdErrSetCast:
2054720601 case IrInstructionIdIntToFloat:
2054820602 case IrInstructionIdFloatToInt:
2054920603 case IrInstructionIdBoolToInt:
src/ir_print.cpp+11
......@@ -664,6 +664,14 @@ static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instructio
664664 fprintf(irp->f, ")");
665665}
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
667675static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) {
668676 fprintf(irp->f, "@intToFloat(");
669677 ir_print_other_instruction(irp, instruction->dest_type);
......@@ -1461,6 +1469,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14611469 case IrInstructionIdFloatCast:
14621470 ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction);
14631471 break;
1472 case IrInstructionIdErrSetCast:
1473 ir_print_err_set_cast(irp, (IrInstructionErrSetCast *)instruction);
1474 break;
14641475 case IrInstructionIdIntToFloat:
14651476 ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction);
14661477 break;
test/cases/error.zig+2-2
......@@ -124,8 +124,8 @@ const Set2 = error{
124124};
125125
126126fn testExplicitErrorSetCast(set1: Set1) void {
127 var x = Set2(set1);
128 var y = Set1(x);
127 var x = @errSetCast(Set2, set1);
128 var y = @errSetCast(Set1, x);
129129 assert(y == error.A);
130130}
131131